quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit cae2f55bb924a2395dafe8fec60090b10468d40a
parent 9825c8018d800a581f6b83cab4ad782871176336
Author: Iván Ávalos <avalos@disroot.org>
Date:   Mon, 27 May 2024 12:27:50 -0600

thread safe multi_add_handle + add/cancel queues

Diffstat:
Mquickjs/quickjs-http.c | 45++++++++++++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/quickjs/quickjs-http.c b/quickjs/quickjs-http.c @@ -37,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; @@ -66,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); @@ -302,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; @@ -332,9 +336,9 @@ 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); } } @@ -382,14 +386,23 @@ curl_multi_thread_run(void *cls) } do { - // Remove cancelled requests in queue + + // 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->request_list) { - struct CurlRequestState *crs = list_entry(el, struct CurlRequestState, link); - if (crs->cancelled) { - curl_multi_remove_handle(ccs->curlm, crs->curl); - list_del(el); - } + 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); @@ -437,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); @@ -493,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);