pthread_cond_broadcast(&c->cond);
}
+struct virThreadArgs {
+ virThreadFunc func;
+ void *opaque;
+};
+
+static void *virThreadHelper(void *data)
+{
+ struct virThreadArgs *args = data;
+ args->func(args->opaque);
+ return NULL;
+}
+
+int virThreadCreate(virThreadPtr thread,
+ bool joinable,
+ virThreadFunc func,
+ void *opaque)
+{
+ struct virThreadArgs args = { func, opaque };
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ if (!joinable)
+ pthread_attr_setdetachstate(&attr, 1);
+
+ int ret = pthread_create(&thread->thread, &attr, virThreadHelper, &args);
+ if (ret != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+void virThreadSelf(virThreadPtr thread)
+{
+ thread->thread = pthread_self();
+}
+
+bool virThreadIsSelf(virThreadPtr thread)
+{
+ return pthread_equal(pthread_self(), thread->thread) ? true : false;
+}
+
+void virThreadJoin(virThreadPtr thread)
+{
+ pthread_join(thread->thread, NULL);
+}
int virThreadLocalInit(virThreadLocalPtr l,
virThreadLocalCleanup c)
#include <config.h>
+#include <process.h>
+
#include "memory.h"
struct virThreadLocalData {
virMutex virThreadLocalLock;
unsigned int virThreadLocalCount = 0;
virThreadLocalDataPtr virThreadLocalList = NULL;
-
+DWORD selfkey;
virThreadLocal virCondEvent;
return -1;
if (virThreadLocalInit(&virCondEvent, virCondEventCleanup) < 0)
return -1;
-
+ if ((selfkey = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ return -1;
return 0;
}
}
+struct virThreadArgs {
+ virThreadFunc func;
+ void *opaque;
+};
+
+static void virThreadHelperDaemon(void *data)
+{
+ struct virThreadArgs *args = data;
+ virThread self;
+ HANDLE handle = GetCurrentThread();
+ HANDLE process = GetCurrentProcess();
+
+ self.joinable = false;
+ DuplicateHandle(process, handle, process,
+ &self.thread, 0, FALSE,
+ DUPLICATE_SAME_ACCESS);
+ TlsSetValue(selfkey, &self);
+
+ args->func(args->opaque);
+
+ TlsSetValue(selfkey, NULL);
+ CloseHandle(self.thread);
+}
+
+static unsigned int __stdcall virThreadHelperJoinable(void *data)
+{
+ struct virThreadArgs *args = data;
+ virThread self;
+ HANDLE handle = GetCurrentThread();
+ HANDLE process = GetCurrentProcess();
+
+ self.joinable = true;
+ DuplicateHandle(process, handle, process,
+ &self.thread, 0, FALSE,
+ DUPLICATE_SAME_ACCESS);
+ TlsSetValue(selfkey, &self);
+
+ args->func(args->opaque);
+
+ TlsSetValue(selfkey, NULL);
+ CloseHandle(self.thread);
+ return 0;
+}
+
+int virThreadCreate(virThreadPtr thread,
+ bool joinable,
+ virThreadFunc func,
+ void *opaque)
+{
+ struct virThreadArgs args = { func, opaque };
+ thread->joinable = joinable;
+ if (joinable) {
+ thread->thread = (HANDLE)_beginthreadex(NULL, 0,
+ virThreadHelperJoinable,
+ &args, 0, NULL);
+ if (thread->thread == 0)
+ return -1;
+ } else {
+ thread->thread = (HANDLE)_beginthread(virThreadHelperDaemon,
+ 0, &args);
+ if (thread->thread == (HANDLE)-1L)
+ return -1;
+ }
+ return 0;
+}
+
+void virThreadSelf(virThreadPtr thread)
+{
+ virThreadPtr self = TlsGetValue(selfkey);
+ thread->thread = self->thread;
+ thread->joinable = self->joinable;
+}
+
+bool virThreadIsSelf(virThreadPtr thread)
+{
+ virThread self;
+ virThreadSelf(&self);
+ return self.thread == thread->thread ? true : false;
+}
+
+void virThreadJoin(virThreadPtr thread)
+{
+ if (thread->joinable) {
+ WaitForSingleObject(thread->thread, INFINITE);
+ CloseHandle(thread->thread);
+ thread->thread = 0;
+ thread->joinable = false;
+ }
+}
+
int virThreadLocalInit(virThreadLocalPtr l,
virThreadLocalCleanup c)
#ifndef __THREADS_H_
# define __THREADS_H_
+# include <stdbool.h>
+
# include "internal.h"
typedef struct virMutex virMutex;
typedef struct virThreadLocal virThreadLocal;
typedef virThreadLocal *virThreadLocalPtr;
+typedef struct virThread virThread;
+typedef virThread *virThreadPtr;
+
int virThreadInitialize(void) ATTRIBUTE_RETURN_CHECK;
void virThreadOnExit(void);
+typedef void (*virThreadFunc)(void *opaque);
+
+int virThreadCreate(virThreadPtr thread,
+ bool joinable,
+ virThreadFunc func,
+ void *opaque) ATTRIBUTE_RETURN_CHECK;
+void virThreadSelf(virThreadPtr thread);
+bool virThreadIsSelf(virThreadPtr thread);
+void virThreadJoin(virThreadPtr thread);
+
int virMutexInit(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
int virMutexInitRecursive(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
void virMutexDestroy(virMutexPtr m);