[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]