[libvirt] [PATCH] threadpool: Switch to detached threads

Jiri Denemark jdenemar at redhat.com
Thu May 21 09:57:52 UTC 2015


Using joinable threads does not help anything, but it can lead to memory
leaks.

When a worker thread exits, it decreases nWorkers or nPrioWorkers and
once both nWorkers and nPrioWorkers are zero (i.e., the last worker is
gone), quit_cond is signaled. When freeing the pool we first tell all
threads to die and then we are waiting for both nWorkers and
nPrioWorkers to become zero. At this point we already know all threads
are gone. So the only reason for calling virThreadJoin of all workers is
to free the memory allocated for joinable threads. If we avoid
allocating this memory, we don't need to take care of freeing it.

Moreover, any memory associated with a worker thread which died before
we asked it to die (e.g., because virCondWait failed in the thread)
would be lost anyway since virThreadPoolFree calls virThreadJoin only
for threads which were running at the time virThreadPoolFree was called.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/util/virthreadpool.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/src/util/virthreadpool.c b/src/util/virthreadpool.c
index ed22486..f640448 100644
--- a/src/util/virthreadpool.c
+++ b/src/util/virthreadpool.c
@@ -201,7 +201,7 @@ virThreadPoolNewFull(size_t minWorkers,
         data->cond = &pool->cond;
 
         if (virThreadCreateFull(&pool->workers[i],
-                                true,
+                                false,
                                 virThreadPoolWorker,
                                 pool->jobFuncName,
                                 true,
@@ -225,7 +225,7 @@ virThreadPoolNewFull(size_t minWorkers,
             data->priority = true;
 
             if (virThreadCreateFull(&pool->prioWorkers[i],
-                                    true,
+                                    false,
                                     virThreadPoolWorker,
                                     pool->jobFuncName,
                                     true,
@@ -249,16 +249,11 @@ void virThreadPoolFree(virThreadPoolPtr pool)
 {
     virThreadPoolJobPtr job;
     bool priority = false;
-    size_t i;
-    size_t nWorkers;
-    size_t nPrioWorkers;
 
     if (!pool)
         return;
 
     virMutexLock(&pool->mutex);
-    nWorkers = pool->nWorkers;
-    nPrioWorkers = pool->nPrioWorkers;
     pool->quit = true;
     if (pool->nWorkers > 0)
         virCondBroadcast(&pool->cond);
@@ -275,12 +270,6 @@ void virThreadPoolFree(virThreadPoolPtr pool)
         VIR_FREE(job);
     }
 
-    for (i = 0; i < nWorkers; i++)
-        virThreadJoin(&pool->workers[i]);
-
-    for (i = 0; i < nPrioWorkers; i++)
-        virThreadJoin(&pool->prioWorkers[i]);
-
     VIR_FREE(pool->workers);
     virMutexUnlock(&pool->mutex);
     virMutexDestroy(&pool->mutex);
@@ -338,7 +327,7 @@ int virThreadPoolSendJob(virThreadPoolPtr pool,
         data->cond = &pool->cond;
 
         if (virThreadCreateFull(&pool->workers[pool->nWorkers - 1],
-                                true,
+                                false,
                                 virThreadPoolWorker,
                                 pool->jobFuncName,
                                 true,
-- 
2.4.1




More information about the libvir-list mailing list