2010/11/8 Daniel P. Berrange <berrange(a)redhat.com>:
The util/threads.c/h code already has APIs for mutexes,
condition variables and thread locals. This commit adds
in code for actually creating threads.
* src/libvirt_private.syms: Export new symbols
* src/util/threads.h: Define APIs virThreadCreate, virThreadSelf,
virThreadIsSelf and virThreadJoin
* src/util/threads-win32.c, src/util/threads-win32.h: Win32
impl of threads
* src/util/threads-pthread.c, src/util/threads-pthread.h: POSIX
impl of threads
struct virThreadLocalData {
@@ -33,7 +35,7 @@ typedef virThreadLocalData *virThreadLocalDataPtr;
virMutex virThreadLocalLock;
unsigned int virThreadLocalCount = 0;
virThreadLocalDataPtr virThreadLocalList = NULL;
-
+DWORD selfkey;
virThreadLocal virCondEvent;
Not introduced by this patch, but why are this local variables not
marked as static?
+
+static unsigned int __stdcall virThreadHelperDaemon(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;
+}
IMHO virThreadHelperJoinable would be a better name for this function.
+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,
+ virThreadHelperDaemon,
+ &args, 0, NULL);
+ if (thread->thread == 0)
+ return -1;
+ } else {
+ thread->thread = (HANDLE)_beginthread(virThreadHelper, 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;
+ }
+}
+
ACK.
Matthias