From c4facdc1977dd0e6fb8b40ee8be75f66bc79a54e Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Wed, 11 Dec 2024 10:50:09 +0800 Subject: [PATCH] erofs-utils: lib: get rid of pthread_cancel() for workqueue Since bionic (Android's libc) does not have pthread_cancel(), call erofs_destroy_workqueue() when initialization fails. Reviewed-by: Yifan Zhao Cc: Kelvin Zhang Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20241211025009.3393476-1-hsiangkao@linux.alibaba.com --- lib/compress.c | 4 ++- lib/workqueue.c | 66 ++++++++++++++++++++++++------------------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/lib/compress.c b/lib/compress.c index c679843..65edd00 100644 --- a/lib/compress.c +++ b/lib/compress.c @@ -1790,7 +1790,9 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s cfg.c_mt_workers << 2, z_erofs_mt_wq_tls_alloc, z_erofs_mt_wq_tls_free); - z_erofs_mt_enabled = !ret; + if (ret) + return ret; + z_erofs_mt_enabled = true; } pthread_mutex_init(&g_ictx.mutex, NULL); pthread_cond_init(&g_ictx.cond, NULL); diff --git a/lib/workqueue.c b/lib/workqueue.c index 47cec9b..18ee0f9 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -15,9 +15,9 @@ static void *worker_thread(void *arg) while (true) { pthread_mutex_lock(&wq->lock); - while (wq->job_count == 0 && !wq->shutdown) + while (!wq->job_count && !wq->shutdown) pthread_cond_wait(&wq->cond_empty, &wq->lock); - if (wq->job_count == 0 && wq->shutdown) { + if (!wq->job_count && wq->shutdown) { pthread_mutex_unlock(&wq->lock); break; } @@ -40,6 +40,30 @@ static void *worker_thread(void *arg) return NULL; } +int erofs_destroy_workqueue(struct erofs_workqueue *wq) +{ + if (!wq) + return -EINVAL; + + pthread_mutex_lock(&wq->lock); + wq->shutdown = true; + pthread_cond_broadcast(&wq->cond_empty); + pthread_mutex_unlock(&wq->lock); + + while (wq->nworker) { + int ret = -pthread_join(wq->workers[wq->nworker - 1], NULL); + + if (ret) + return ret; + --wq->nworker; + } + free(wq->workers); + pthread_mutex_destroy(&wq->lock); + pthread_cond_destroy(&wq->cond_empty); + pthread_cond_destroy(&wq->cond_full); + return 0; +} + int erofs_alloc_workqueue(struct erofs_workqueue *wq, unsigned int nworker, unsigned int max_jobs, erofs_wq_func_t on_start, erofs_wq_func_t on_exit) @@ -51,7 +75,6 @@ int erofs_alloc_workqueue(struct erofs_workqueue *wq, unsigned int nworker, return -EINVAL; wq->head = wq->tail = NULL; - wq->nworker = nworker; wq->max_jobs = max_jobs; wq->job_count = 0; wq->shutdown = false; @@ -66,15 +89,14 @@ int erofs_alloc_workqueue(struct erofs_workqueue *wq, unsigned int nworker, return -ENOMEM; for (i = 0; i < nworker; i++) { - ret = pthread_create(&wq->workers[i], NULL, worker_thread, wq); - if (ret) { - while (i) - pthread_cancel(wq->workers[--i]); - free(wq->workers); - return ret; - } + ret = -pthread_create(&wq->workers[i], NULL, worker_thread, wq); + if (ret) + break; } - return 0; + wq->nworker = i; + if (ret) + erofs_destroy_workqueue(wq); + return ret; } int erofs_queue_work(struct erofs_workqueue *wq, struct erofs_work *work) @@ -99,25 +121,3 @@ int erofs_queue_work(struct erofs_workqueue *wq, struct erofs_work *work) pthread_mutex_unlock(&wq->lock); return 0; } - -int erofs_destroy_workqueue(struct erofs_workqueue *wq) -{ - unsigned int i; - - if (!wq) - return -EINVAL; - - pthread_mutex_lock(&wq->lock); - wq->shutdown = true; - pthread_cond_broadcast(&wq->cond_empty); - pthread_mutex_unlock(&wq->lock); - - for (i = 0; i < wq->nworker; i++) - pthread_join(wq->workers[i], NULL); - - free(wq->workers); - pthread_mutex_destroy(&wq->lock); - pthread_cond_destroy(&wq->cond_empty); - pthread_cond_destroy(&wq->cond_full); - return 0; -} -- 2.34.1