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(a)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