From: Hitoshi Mitake <[email protected]>

Previous protection scheme of wi->nr_thread in work.c was
unclear because wi->startup_lock was also used for protecting it
during workqueue grow/shrink. This patch let work.c protect
wi->nr_thread by the new wi->workers_lock.

Signed-off-by: Hitoshi Mitake <[email protected]>
---
 lib/work.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

v3:
 - add a new mutex for protecting nr_threads and procedure of wq grow/shrink

diff --git a/lib/work.c b/lib/work.c
index 84eb727..e973519 100644
--- a/lib/work.c
+++ b/lib/work.c
@@ -68,6 +68,9 @@ struct worker_info {
        pthread_mutex_t pending_lock;
        /* protected by pending_lock */
        struct work_queue q;
+
+       pthread_mutex_t workers_lock;
+       /* protected by workers_lock */
        size_t nr_threads;
 
        /* protected by uatomic primitives */
@@ -145,18 +148,18 @@ static int create_worker_threads(struct worker_info *wi, 
size_t nr_threads)
        pthread_t thread;
        int ret;
 
-       pthread_mutex_lock(&wi->startup_lock);
+       pthread_mutex_lock(&wi->workers_lock);
        while (wi->nr_threads < nr_threads) {
                ret = pthread_create(&thread, NULL, worker_routine, wi);
                if (ret != 0) {
                        sd_err("failed to create worker thread: %m");
-                       pthread_mutex_unlock(&wi->startup_lock);
+                       pthread_mutex_unlock(&wi->workers_lock);
                        return -1;
                }
                wi->nr_threads++;
                sd_debug("create thread %s %zu", wi->name, wi->nr_threads);
        }
-       pthread_mutex_unlock(&wi->startup_lock);
+       pthread_mutex_unlock(&wi->workers_lock);
 
        return 0;
 }
@@ -293,7 +296,11 @@ static void *worker_routine(void *arg)
 
                pthread_mutex_lock(&wi->pending_lock);
                if (wq_need_shrink(wi)) {
+                       pthread_mutex_unlock(&wi->pending_lock);
+
+                       pthread_mutex_lock(&wi->workers_lock);
                        wi->nr_threads--;
+                       pthread_mutex_unlock(&wi->workers_lock);
 
 #ifdef ENABLE_TRACE
                        pthread_mutex_lock(&tid_map_lock);
@@ -301,7 +308,6 @@ static void *worker_routine(void *arg)
                        pthread_mutex_unlock(&tid_map_lock);
 #endif
 
-                       pthread_mutex_unlock(&wi->pending_lock);
                        pthread_detach(pthread_self());
                        sd_debug("destroy thread %s %d, %zu", wi->name, tid,
                                 wi->nr_threads);
-- 
1.7.10.4

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to