summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2024-03-02 18:42:28 +0800
committerMole Shang <[email protected]>2024-03-02 18:42:28 +0800
commit3e5ebc6dbd12f9a176baa6106a9b9f4ec5ba7346 (patch)
tree4f6b5850a79e8831474d25cf6c86b3d4ab1a3d30
parentce6c2dcbaff65ef5f9f817f3a8c50c8a1a8094eb (diff)
downloadhinata-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.c38
-rw-r--r--src/process_url.h1
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 {