diff options
author | Mole Shang <[email protected]> | 2024-03-02 18:42:28 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-03-02 18:42:28 +0800 |
commit | 3e5ebc6dbd12f9a176baa6106a9b9f4ec5ba7346 (patch) | |
tree | 4f6b5850a79e8831474d25cf6c86b3d4ab1a3d30 | |
parent | ce6c2dcbaff65ef5f9f817f3a8c50c8a1a8094eb (diff) | |
download | hinata-3e5ebc6dbd12f9a176baa6106a9b9f4ec5ba7346.tar.gz hinata-3e5ebc6dbd12f9a176baa6106a9b9f4ec5ba7346.tar.bz2 hinata-3e5ebc6dbd12f9a176baa6106a9b9f4ec5ba7346.zip |
process_url: merge_and_cleanup: do not block ui thread
-rw-r--r-- | src/process_url.c | 38 | ||||
-rw-r--r-- | src/process_url.h | 1 |
2 files changed, 26 insertions, 13 deletions
diff --git a/src/process_url.c b/src/process_url.c index 00bc696..c5689c1 100644 --- a/src/process_url.c +++ b/src/process_url.c @@ -45,7 +45,7 @@ static callback_t callback_g; static callback_struct_t *p_callback_struct_g; static CURLU *h; -/*NOTE: Use logger(X) (defined as a generic macro) to log errors. */ +/* NOTE: Use logger(X) (defined as a generic macro) to log errors. */ static bool logerr_b(CURLcode r) { if (r && !corrupted) { LOG("libcurl", "Error %d: %s\n", r, ERRTOSTRING(r)); @@ -350,7 +350,10 @@ static int pull_part(void *a) { return (int)res; } -static int merge_and_cleanup(curl_conf_t *curl_c) { +static int merge_and_cleanup(void *p_curl_c) { + curl_conf_t *curl_c = *(curl_conf_t **)p_curl_c; + // Now sets the global (curl_conf_t *)curl_conf to NULL + *(curl_conf_t **)p_curl_c = NULL; if (corrupted) { append_log("Cancelling...\n"); } else { @@ -386,12 +389,22 @@ static int merge_and_cleanup(curl_conf_t *curl_c) { append_log("Error deleting file %s\n", curl_c->outfn); } } - append_log("Download %s finished.\n", curl_conf->outfn); - // Reset stat + append_log("Download %s finished.\n", curl_c->outfn); + + bool need_callback = curl_c->need_callback; + // Cleanup stat before creating the callback thread to avoid mem overlap curl_c->success_thrd = 0; curl_c->total_thrd = 0; FREE_AND_NULLIFY(curl_c->URL); FREE_AND_NULLIFY(curl_c->outfn); + FREE_AND_NULLIFY(curl_c); + + // Perform the callback (if any) + if (need_callback) { + thrd_t cb_thrd; + thrd_create(&cb_thrd, callback_g, p_callback_struct_g); + thrd_detach(cb_thrd); + } return 0; } @@ -500,7 +513,7 @@ void curl_cleanup(status_t *stat) { } mtx_unlock(&mtx); if (!stat->is_done) { - merge_and_cleanup(curl_conf); + merge_and_cleanup(&curl_conf); } mtx_destroy(&mtx); cnd_destroy(&cnd); @@ -543,14 +556,13 @@ void poll_status(status_t *stat) { int r; thrd_join(tid[i], &r); } - merge_and_cleanup(curl_conf); - FREE_AND_NULLIFY(curl_conf); - // Perform the callback - if (is_empty_queue(&dl_queue) && callback_g && !corrupted) { - thrd_t cb_thrd; - thrd_create(&cb_thrd, callback_g, p_callback_struct_g); - thrd_detach(cb_thrd); - } + // Do we need to perform callback? + if (is_empty_queue(&dl_queue) && callback_g && !corrupted) + curl_conf->need_callback = true; + // Do not block ui thread while erging + thrd_t mg_thrd; + thrd_create(&mg_thrd, merge_and_cleanup, (void *)&curl_conf); + thrd_detach(mg_thrd); corrupted = false; } mtx_unlock(&mtx); diff --git a/src/process_url.h b/src/process_url.h index 76fe574..5b2542c 100644 --- a/src/process_url.h +++ b/src/process_url.h @@ -24,6 +24,7 @@ typedef struct curl_conf { char *outfn; str_array_t partfn; FILE *fplist[MAX_THREAD]; + bool need_callback; } curl_conf_t; typedef struct thrd_info { |