[libvirt] [PATCH 02/10] thread: Create thread local condition for every thread

Jiri Denemark jdenemar at redhat.com
Thu May 21 22:42:35 UTC 2015


So that any code can call virThreadQueueRegister whenever it needs to
wait for some event. The thread condition will be automatically
invalidated (and thus ignored by virThreadQueue{Signal,Broadcast})
whenever its thread exits to avoid deadlocks or crashes.

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

diff --git a/src/util/virthread.c b/src/util/virthread.c
index 6c49515..8e2e230 100644
--- a/src/util/virthread.c
+++ b/src/util/virthread.c
@@ -30,7 +30,9 @@
 #endif
 
 #include "viralloc.h"
+#include "virobject.h"
 #include "virthreadjob.h"
+#include "virthreadqueue.h"
 
 
 /* Nothing special required for pthreads */
@@ -187,6 +189,7 @@ struct virThreadArgs {
     virThreadFunc func;
     const char *funcName;
     bool worker;
+    virThreadCondPtr cond;
     void *opaque;
 };
 
@@ -198,6 +201,8 @@ static void *virThreadHelper(void *data)
     /* Free args early, rather than tying it up during the entire thread.  */
     VIR_FREE(args);
 
+    virThreadCondInit(local.cond);
+
     if (local.worker)
         virThreadJobSetWorker(local.funcName);
     else
@@ -208,6 +213,8 @@ static void *virThreadHelper(void *data)
     if (!local.worker)
         virThreadJobClear(0);
 
+    virThreadCondInvalidate();
+
     return NULL;
 }
 
@@ -218,7 +225,7 @@ int virThreadCreateFull(virThreadPtr thread,
                         bool worker,
                         void *opaque)
 {
-    struct virThreadArgs *args;
+    struct virThreadArgs *args = NULL;
     pthread_attr_t attr;
     int ret = -1;
     int err;
@@ -234,22 +241,28 @@ int virThreadCreateFull(virThreadPtr thread,
     args->funcName = funcName;
     args->worker = worker;
     args->opaque = opaque;
+    if (!(args->cond = virThreadCondNew()))
+        goto cleanup;
 
     if (!joinable)
         pthread_attr_setdetachstate(&attr, 1);
 
     err = pthread_create(&thread->thread, &attr, virThreadHelper, args);
-    if (err != 0) {
-        VIR_FREE(args);
+    if (err != 0)
         goto cleanup;
-    }
     /* New thread owns 'args' in success case, so don't free */
+    args = NULL;
 
     ret = 0;
+
  cleanup:
     pthread_attr_destroy(&attr);
     if (ret < 0)
         errno = err;
+    if (args) {
+        virObjectUnref(args->cond);
+        VIR_FREE(args);
+    }
     return ret;
 }
 
-- 
2.4.1




More information about the libvir-list mailing list