[libvirt] [PATCH 1/2] Add a parameter to virThreadPoolSendJob() to let the caller decide whether to wait for the job to complete

Hu Tao hutao at cn.fujitsu.com
Thu Dec 23 09:07:18 UTC 2010


---
 src/qemu/qemu_driver.c |    2 +-
 src/util/threadpool.c  |   19 ++++++++++++++++++-
 src/util/threadpool.h  |    3 ++-
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 924446f..aa2e805 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -665,7 +665,7 @@ qemuHandleDomainWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
         if (VIR_ALLOC(wdEvent) == 0) {
             wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
             wdEvent->vm = vm;
-            ignore_value(virThreadPoolSendJob(driver->workerPool, wdEvent));
+            ignore_value(virThreadPoolSendJob(driver->workerPool, wdEvent, false));
         } else
             virReportOOMError();
     }
diff --git a/src/util/threadpool.c b/src/util/threadpool.c
index 1213862..07f2fcf 100644
--- a/src/util/threadpool.c
+++ b/src/util/threadpool.c
@@ -42,6 +42,7 @@ struct _virThreadPoolJob {
     virThreadPoolJobPtr next;
 
     void *data;
+    virCondPtr complete;
 };
 
 typedef struct _virThreadPoolJobList virThreadPoolJobList;
@@ -73,6 +74,7 @@ struct _virThreadPool {
 static void virThreadPoolWorker(void *opaque)
 {
     virThreadPoolPtr pool = opaque;
+    virCondPtr complete;
 
     virMutexLock(&pool->mutex);
 
@@ -97,9 +99,12 @@ static void virThreadPoolWorker(void *opaque)
             pool->jobList.tail = &pool->jobList.head;
 
         virMutexUnlock(&pool->mutex);
+        complete = job->complete;
         (pool->jobFunc)(job->data, pool->jobOpaque);
         VIR_FREE(job);
         virMutexLock(&pool->mutex);
+        if (complete)
+            virCondSignal(complete);
     }
 
 out:
@@ -188,9 +193,14 @@ void virThreadPoolFree(virThreadPoolPtr pool)
 }
 
 int virThreadPoolSendJob(virThreadPoolPtr pool,
-                         void *jobData)
+                         void *jobData,
+                         bool waitForCompletion)
 {
     virThreadPoolJobPtr job;
+    virCond complete;
+
+    if (waitForCompletion && virCondInit(&complete) < 0)
+        return -1;
 
     virMutexLock(&pool->mutex);
     if (pool->quit)
@@ -219,10 +229,17 @@ int virThreadPoolSendJob(virThreadPoolPtr pool,
 
     job->data = jobData;
     job->next = NULL;
+    job->complete = NULL;
     *pool->jobList.tail = job;
     pool->jobList.tail = &(*pool->jobList.tail)->next;
 
     virCondSignal(&pool->cond);
+
+    if (waitForCompletion) {
+        job->complete = &complete;
+        virCondWait(&complete, &pool->mutex);
+    }
+
     virMutexUnlock(&pool->mutex);
 
     return 0;
diff --git a/src/util/threadpool.h b/src/util/threadpool.h
index 5714b0b..6f763dc 100644
--- a/src/util/threadpool.h
+++ b/src/util/threadpool.h
@@ -41,7 +41,8 @@ virThreadPoolPtr virThreadPoolNew(size_t minWorkers,
 void virThreadPoolFree(virThreadPoolPtr pool);
 
 int virThreadPoolSendJob(virThreadPoolPtr pool,
-                         void *jobdata) ATTRIBUTE_NONNULL(1)
+                         void *jobdata,
+                         bool waitForCompletion) ATTRIBUTE_NONNULL(1)
                                         ATTRIBUTE_NONNULL(2)
                                         ATTRIBUTE_RETURN_CHECK;
 
-- 
1.7.3.1


-- 
Thanks,
Hu Tao




More information about the libvir-list mailing list