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 --- src/libvirt_private.syms | 4 +++ src/util/threads-pthread.c | 45 ++++++++++++++++++++++++++++++++++++++++++ src/util/threads-pthread.h | 4 +++ src/util/threads-win32.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/util/threads-win32.h | 3 ++ src/util/threads.h | 15 ++++++++++++++ 6 files changed, 118 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 693e2ed..d8287ce 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -713,6 +713,10 @@ virMutexInit; virMutexInitRecursive; virMutexLock; virMutexUnlock; +virThreadCreate; +virThreadIsSelf; +virThreadJoin; +virThreadSelf; # usb.h diff --git a/src/util/threads-pthread.c b/src/util/threads-pthread.c index 030b33f..0bc413c 100644 --- a/src/util/threads-pthread.c +++ b/src/util/threads-pthread.c @@ -129,6 +129,51 @@ void virCondBroadcast(virCondPtr c) 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_self() == thread->thread ? true : false; +} + +void virThreadJoin(virThreadPtr thread) +{ + pthread_join(thread->thread, NULL); +} int virThreadLocalInit(virThreadLocalPtr l, virThreadLocalCleanup c) diff --git a/src/util/threads-pthread.h b/src/util/threads-pthread.h index 6404d1d..b25d0c2 100644 --- a/src/util/threads-pthread.h +++ b/src/util/threads-pthread.h @@ -31,6 +31,10 @@ struct virCond { pthread_cond_t cond; }; +struct virThread { + pthread_t thread; +}; + struct virThreadLocal { pthread_key_t key; }; diff --git a/src/util/threads-win32.c b/src/util/threads-win32.c index fe1fcd0..3f69f41 100644 --- a/src/util/threads-win32.c +++ b/src/util/threads-win32.c @@ -21,6 +21,8 @@ #include <config.h> +#include <process.h> + #include "memory.h" struct virThreadLocalData { @@ -205,6 +207,51 @@ void virCondBroadcast(virCondPtr c) } +struct virThreadArgs { + virThreadFunc func; + void *opaque; +}; + +static unsigned int __stdcall virThreadHelper(void *data) +{ + struct virThreadArgs *args = data; + args->func(args->opaque); + return 0; +} + +int virThreadCreate(virThreadPtr thread, + bool joinable ATTRIBUTE_UNUSED, + virThreadFunc func, + void *opaque) +{ + struct virThreadArgs args = { func, opaque }; + thread->thread = (HANDLE)_beginthreadex(NULL, 0, virThreadHelper, &args, 0, NULL); + return 0; +} + +void virThreadSelf(virThreadPtr thread) +{ + HANDLE handle = GetCurrentThread(); + HANDLE process = GetCurrentProcess(); + + DuplicateHandle(process, handle, process, + &thread->thread, 0, FALSE, + DUPLICATE_SAME_ACCESS); +} + +bool virThreadIsSelf(virThreadPtr thread) +{ + virThread self; + virThreadSelf(&self); + return self.thread == thread->thread ? true : false; +} + +void virThreadJoin(virThreadPtr thread) +{ + WaitForSingleObject(thread->thread, INFINITE); + CloseHandle(thread->thread); +} + int virThreadLocalInit(virThreadLocalPtr l, virThreadLocalCleanup c) diff --git a/src/util/threads-win32.h b/src/util/threads-win32.h index 783d91d..7142884 100644 --- a/src/util/threads-win32.h +++ b/src/util/threads-win32.h @@ -33,6 +33,9 @@ struct virCond { HANDLE *waiters; }; +struct virThread { + HANDLE thread; +}; struct virThreadLocal { DWORD key; diff --git a/src/util/threads.h b/src/util/threads.h index db54ea0..b3b827d 100644 --- a/src/util/threads.h +++ b/src/util/threads.h @@ -22,6 +22,8 @@ #ifndef __THREADS_H_ # define __THREADS_H_ +# include <stdbool.h> + # include "internal.h" typedef struct virMutex virMutex; @@ -33,10 +35,23 @@ typedef virCond *virCondPtr; 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); -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list