[libvirt] [PATCH 07/11] Introduce portability APIs for creating threads
Matthias Bolte
matthias.bolte at googlemail.com
Mon Nov 8 22:40:00 UTC 2010
2010/11/8 Daniel P. Berrange <berrange at 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
More information about the libvir-list
mailing list