[libvirt] [PATCH 07/11] Introduce portability APIs for creating threads
Daniel P. Berrange
berrange at redhat.com
Tue Nov 2 17:49:11 UTC 2010
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
More information about the libvir-list
mailing list