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

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

 



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

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]