[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