gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-quickjs-tart] branch master updated (b96f661 -> cae2f55)


From: gnunet
Subject: [taler-quickjs-tart] branch master updated (b96f661 -> cae2f55)
Date: Mon, 27 May 2024 21:47:41 +0200

This is an automated email from the git hooks/post-receive script.

ivan-avalos pushed a change to branch master
in repository quickjs-tart.

    from b96f661  android: bump qtart version to 0.10.10
     new f7b6b6b  make os.fetchHttp return cancellation function
     new 5ae4ad7  inject request ID into os.fetchHttp cancelFn
     new 9825c80  real request cancellation in cURL client
     new cae2f55  thread safe multi_add_handle + add/cancel queues

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 quickjs/quickjs-http.c | 47 +++++++++++++++++++++++++++++++++++++++--------
 quickjs/quickjs-libc.c | 43 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/quickjs/quickjs-http.c b/quickjs/quickjs-http.c
index e303b28..cabb6c2 100644
--- a/quickjs/quickjs-http.c
+++ b/quickjs/quickjs-http.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <assert.h>
 
+#include "curl/multi.h"
 #include "cutils.h"
 #include "quickjs-http.h"
 #include "list.h"
@@ -36,11 +37,15 @@ struct CurlClientState {
     CURLM *curlm;
     int last_request_id;
     struct list_head request_list; /* list of CurlRequestState.link */
+    struct list_head add_queue;    /* multi_add_handle queue */
+    struct list_head cancel_queue; /* multi_remove_handle queue */
 };
 
 struct CurlRequestState {
     struct CurlClientState *ccs;
-    struct list_head link;
+    struct list_head link_req;    /* for request_list */
+    struct list_head link_add;    /* for add_queue */
+    struct list_head link_cancel; /* for cancel_queue */
     DynBuf response_data;
     BOOL cancelled;
     CURL *curl;
@@ -65,7 +70,7 @@ static void destroy_curl_request_state(struct 
CurlRequestState *crs)
     ccs = crs->ccs;
     crs->ccs = NULL;
 
-    list_del(&crs->link);
+    list_del(&crs->link_req);
     curl_slist_free_all(crs->req_headers);
     curl_slist_free_all(crs->resp_headers);
     dbuf_free(&crs->response_data);
@@ -301,10 +306,10 @@ create_impl(void *cls, struct JSHttpRequestInfo *req_info)
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, crs->req_headers);
 
     pthread_mutex_lock(&ccs->mutex);
-    list_add_tail(&crs->link, &ccs->request_list);
+    list_add_tail(&crs->link_add, &ccs->add_queue);
+    list_add_tail(&crs->link_req, &ccs->request_list);
     pthread_mutex_unlock(&ccs->mutex);
 
-    curl_multi_add_handle(ccs->curlm, curl);
     curl_multi_wakeup(ccs->curlm);
 
     return crs->request_id;
@@ -331,14 +336,16 @@ destroy_impl(void *cls, int request_id)
     pthread_mutex_lock(&ccs->mutex);
 
     list_for_each(el, &ccs->request_list) {
-        struct CurlRequestState *crs = list_entry(el, struct CurlRequestState, 
link);
-        if (crs->request_id == request_id) {
-          crs->cancelled = TRUE;
+        struct CurlRequestState *crs = list_entry(el, struct CurlRequestState, 
link_req);
+        if (crs->request_id == request_id && !crs->cancelled) {
+            list_add_tail(&crs->link_cancel, &ccs->cancel_queue);
         }
     }
 
     pthread_mutex_unlock(&ccs->mutex);
 
+    curl_multi_wakeup(ccs->curlm);
+
     return 0;
 }
 
@@ -349,6 +356,7 @@ static void *
 curl_multi_thread_run(void *cls)
 {
     struct CurlClientState *ccs = cls;
+    struct list_head *el, *el1;
     int still_running;
     struct CURLMsg *m;
     BOOL stopped;
@@ -378,6 +386,27 @@ curl_multi_thread_run(void *cls)
         }
 
         do {
+
+            // Add new requests in queue
+            pthread_mutex_lock(&ccs->mutex);
+            list_for_each_safe(el, el1, &ccs->add_queue) {
+                struct CurlRequestState *crs = list_entry(el, struct 
CurlRequestState, link_add);
+                curl_multi_add_handle(ccs->curlm, crs->curl);
+                list_del(el);
+            }
+            pthread_mutex_unlock(&ccs->mutex);
+
+            // Cancel requests in queue
+            pthread_mutex_lock(&ccs->mutex);
+            list_for_each_safe(el, el1, &ccs->cancel_queue) {
+                struct CurlRequestState *crs = list_entry(el, struct 
CurlRequestState, link_cancel);
+                curl_multi_remove_handle(ccs->curlm, crs->curl);
+                crs->cancelled = TRUE;
+                list_del(el);
+            }
+            pthread_mutex_unlock(&ccs->mutex);
+
+            // Process finished request
             int msgq = 0;
             m = curl_multi_info_read(ccs->curlm, &msgq);
             if (m && (m->msg == CURLMSG_DONE)) {
@@ -421,6 +450,8 @@ js_curl_http_client_create()
       goto error;
     }
     init_list_head(&ccs->request_list);
+    init_list_head(&ccs->add_queue);
+    init_list_head(&ccs->cancel_queue);
 
     curl_share_setopt(ccs->curlsh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
     curl_share_setopt(ccs->curlsh, CURLSHOPT_SHARE, 
CURL_LOCK_DATA_SSL_SESSION);
@@ -477,7 +508,7 @@ destroy_client_state(struct CurlClientState *ccs)
     }
     pthread_mutex_lock(&ccs->mutex);
     list_for_each_safe(el, el1, &ccs->request_list) {
-        struct CurlRequestState *crs = list_entry(el, struct CurlRequestState, 
link);
+        struct CurlRequestState *crs = list_entry(el, struct CurlRequestState, 
link_req);
         destroy_curl_request_state(crs);
     }
     pthread_mutex_unlock(&ccs->mutex);
diff --git a/quickjs/quickjs-libc.c b/quickjs/quickjs-libc.c
index 0002468..71b1fdd 100644
--- a/quickjs/quickjs-libc.c
+++ b/quickjs/quickjs-libc.c
@@ -22,6 +22,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include "quickjs.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -2286,6 +2287,23 @@ static void handle_http_resp(void *cls, struct 
JSHttpResponseInfo *resp_info)
     return;
 }
 
+static JSValue cancel_http_req(JSContext *ctx, JSValueConst this_val,
+                               int argc, JSValueConst *argv, int magic,
+                               JSValue *func_data)
+{
+    JSRuntime *rt = JS_GetRuntime(ctx);
+    JSThreadState *ts = JS_GetRuntimeOpaque(rt);
+    int req_id;
+    int ret;
+
+    JS_ToInt32(ctx, &req_id, func_data[0]);
+
+    // cancel HTTP request
+    ret = ts->http_client_impl->req_cancel(ts->http_client_impl->cls, req_id);
+
+    return JS_NewInt32(ctx, ret);
+}
+
 static void
 free_http_headers(JSContext *ctx, char **headers)
 {
@@ -2345,7 +2363,10 @@ exception:
 
 
 /**
- * fetchHttp(url, { method, headers, body }): Promise<Response>
+ * fetchHttp(url, { method, headers, body }): {
+ *   response: Promise<Response>,
+ *   cancelFn: () => void,
+ * }
  */
 static JSValue js_os_fetchHttp(JSContext *ctx, JSValueConst this_val,
                                  int argc, JSValueConst *argv)
@@ -2470,13 +2491,27 @@ static JSValue js_os_fetchHttp(JSContext *ctx, 
JSValueConst this_val,
 
     list_add_tail(&req_context->link, &ts->http_requests);
 
-    ret_val = JS_NewPromiseCapability(ctx, resolving_funs);
-    if (JS_IsException(ret_val)) {
-        goto done;
+    // requestId: number
+    JSValue requestId = JS_NewInt32(ctx, ret);
+
+    // promise: Promise<Response>
+    JSValue promise = JS_NewPromiseCapability(ctx, resolving_funs);
+    if (JS_IsException(promise)) {
+        goto exception;
     }
     req_context->request_id = ret;
     req_context->resolve_func = resolving_funs[0];
     req_context->reject_func = resolving_funs[1];
+
+    // cancelFn: () => void
+    JSValue cancelCls = JS_NewInt32(ctx, ret);
+    JSValue cancelFn = JS_NewCFunctionData(ctx, &cancel_http_req, 0, 0, 1, 
&cancelCls);
+
+    ret_val = JS_NewObject(ctx);
+    JS_SetPropertyStr(ctx, ret_val, "requestId", requestId);
+    JS_SetPropertyStr(ctx, ret_val, "promise", promise);
+    JS_SetPropertyStr(ctx, ret_val, "cancelFn", cancelFn);
+
 done:
     free_http_headers(ctx, req.request_headers);
     JS_FreeValue(ctx, method);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]