There are a number of pthreads impls available on Win32
these days, in particular the mingw64 project has a good
impl. Delete the native windows thread implementation and
rely on using pthreads everywhere.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
configure.ac | 15 +-
src/Makefile.am | 4 -
src/util/virthread.c | 291 +++++++++++++++++++++++++++++++-
src/util/virthread.h | 41 ++++-
src/util/virthreadpthread.c | 309 ----------------------------------
src/util/virthreadpthread.h | 53 ------
src/util/virthreadwin32.c | 396 --------------------------------------------
src/util/virthreadwin32.h | 53 ------
8 files changed, 329 insertions(+), 833 deletions(-)
delete mode 100644 src/util/virthreadpthread.c
delete mode 100644 src/util/virthreadpthread.h
delete mode 100644 src/util/virthreadwin32.c
delete mode 100644 src/util/virthreadwin32.h
diff --git a/configure.ac b/configure.ac
index 3a70375..168eb27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,12 +270,21 @@ AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r
\
posix_memalign prlimit regexec sched_getaffinity setgroups setns \
setrlimit symlink sysctlbyname])
-dnl Availability of pthread functions (if missing, win32 threading is
-dnl assumed). Because of $LIB_PTHREAD, we cannot use AC_CHECK_FUNCS_ONCE.
-dnl LIB_PTHREAD and LIBMULTITHREAD were set during gl_INIT by gnulib.
+dnl Availability of pthread functions. Because of $LIB_PTHREAD, we
+dnl cannot use AC_CHECK_FUNCS_ONCE. LIB_PTHREAD and LIBMULTITHREAD
+dnl were set during gl_INIT by gnulib.
old_LIBS=$LIBS
LIBS="$LIBS $LIB_PTHREAD $LIBMULTITHREAD"
+
+pthread_found=yes
AC_CHECK_FUNCS([pthread_mutexattr_init])
+AC_CHECK_HEADER([pthread.h],,[pthread_found=no])
+
+if test "$ac_cv_func_pthread_mutexattr_init:$pthread_found" !=
"yes:yes"
+then
+ AC_MSG_ERROR([A pthreads impl is required for building libvirt])
+fi
+
dnl At least mingw64-winpthreads #defines pthread_sigmask to 0,
dnl which in turn causes compilation to complain about unused variables.
dnl Expose this broken implementation, so we can work around it.
diff --git a/src/Makefile.am b/src/Makefile.am
index 8f77658..2298fdb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -141,8 +141,6 @@ UTIL_SOURCES = \
util/virsysinfo.c util/virsysinfo.h \
util/virsystemd.c util/virsystemd.h \
util/virthread.c util/virthread.h \
- util/virthreadpthread.h \
- util/virthreadwin32.h \
util/virthreadpool.c util/virthreadpool.h \
util/virtime.h util/virtime.c \
util/virtpm.h util/virtpm.c \
@@ -165,8 +163,6 @@ util/virkeymaps.h: $(srcdir)/util/keymaps.csv \
$(AM_V_GEN)$(PYTHON) $(srcdir)/util/virkeycode-mapgen.py \
<$(srcdir)/util/keymaps.csv >$(srcdir)/util/virkeymaps.h
-EXTRA_DIST += util/virthreadpthread.c util/virthreadwin32.c
-
# Internal generic driver infrastructure
NODE_INFO_SOURCES = nodeinfo.h nodeinfo.c
DATATYPES_SOURCES = datatypes.h datatypes.c
diff --git a/src/util/virthread.c b/src/util/virthread.c
index dd1768e..b60fb4a 100644
--- a/src/util/virthread.c
+++ b/src/util/virthread.c
@@ -23,12 +23,289 @@
#include "virthread.h"
-/* On mingw, we prefer native threading over the sometimes-broken
- * pthreads-win32 library wrapper. */
-#ifdef WIN32
-# include "virthreadwin32.c"
-#elif defined HAVE_PTHREAD_MUTEXATTR_INIT
-# include "virthreadpthread.c"
+#include <unistd.h>
+#include <inttypes.h>
+#if HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+#endif
+
+#include "viralloc.h"
+
+
+/* Nothing special required for pthreads */
+int virThreadInitialize(void)
+{
+ return 0;
+}
+
+void virThreadOnExit(void)
+{
+}
+
+int virOnce(virOnceControlPtr once, virOnceFunc init)
+{
+ return pthread_once(&once->once, init);
+}
+
+
+int virMutexInit(virMutexPtr m)
+{
+ int ret;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+ ret = pthread_mutex_init(&m->lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+ if (ret != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+int virMutexInitRecursive(virMutexPtr m)
+{
+ int ret;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ ret = pthread_mutex_init(&m->lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+ if (ret != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+void virMutexDestroy(virMutexPtr m)
+{
+ pthread_mutex_destroy(&m->lock);
+}
+
+void virMutexLock(virMutexPtr m){
+ pthread_mutex_lock(&m->lock);
+}
+
+void virMutexUnlock(virMutexPtr m)
+{
+ pthread_mutex_unlock(&m->lock);
+}
+
+
+int virRWLockInit(virRWLockPtr m)
+{
+ if (pthread_rwlock_init(&m->lock, NULL) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+void virRWLockDestroy(virRWLockPtr m)
+{
+ pthread_rwlock_destroy(&m->lock);
+}
+
+
+void virRWLockRead(virRWLockPtr m)
+{
+ pthread_rwlock_rdlock(&m->lock);
+}
+
+void virRWLockWrite(virRWLockPtr m)
+{
+ pthread_rwlock_wrlock(&m->lock);
+}
+
+
+void virRWLockUnlock(virRWLockPtr m)
+{
+ pthread_rwlock_unlock(&m->lock);
+}
+
+int virCondInit(virCondPtr c)
+{
+ int ret;
+ if ((ret = pthread_cond_init(&c->cond, NULL)) != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+int virCondDestroy(virCondPtr c)
+{
+ int ret;
+ if ((ret = pthread_cond_destroy(&c->cond)) != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+int virCondWait(virCondPtr c, virMutexPtr m)
+{
+ int ret;
+ if ((ret = pthread_cond_wait(&c->cond, &m->lock)) != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms)
+{
+ int ret;
+ struct timespec ts;
+
+ ts.tv_sec = whenms / 1000;
+ ts.tv_nsec = (whenms % 1000) * 1000;
+
+ if ((ret = pthread_cond_timedwait(&c->cond, &m->lock, &ts)) != 0)
{
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+void virCondSignal(virCondPtr c)
+{
+ pthread_cond_signal(&c->cond);
+}
+
+void virCondBroadcast(virCondPtr c)
+{
+ pthread_cond_broadcast(&c->cond);
+}
+
+struct virThreadArgs {
+ virThreadFunc func;
+ void *opaque;
+};
+
+static void *virThreadHelper(void *data)
+{
+ struct virThreadArgs *args = data;
+ struct virThreadArgs local = *args;
+
+ /* Free args early, rather than tying it up during the entire thread. */
+ VIR_FREE(args);
+ local.func(local.opaque);
+ return NULL;
+}
+
+int virThreadCreate(virThreadPtr thread,
+ bool joinable,
+ virThreadFunc func,
+ void *opaque)
+{
+ struct virThreadArgs *args;
+ pthread_attr_t attr;
+ int ret = -1;
+ int err;
+
+ if ((err = pthread_attr_init(&attr)) != 0)
+ goto cleanup;
+ if (VIR_ALLOC_QUIET(args) < 0) {
+ err = ENOMEM;
+ goto cleanup;
+ }
+
+ args->func = func;
+ args->opaque = opaque;
+
+ if (!joinable)
+ pthread_attr_setdetachstate(&attr, 1);
+
+ err = pthread_create(&thread->thread, &attr, virThreadHelper, args);
+ if (err != 0) {
+ VIR_FREE(args);
+ goto cleanup;
+ }
+ /* New thread owns 'args' in success case, so don't free */
+
+ ret = 0;
+cleanup:
+ pthread_attr_destroy(&attr);
+ if (ret < 0)
+ errno = err;
+ return ret;
+}
+
+void virThreadSelf(virThreadPtr thread)
+{
+ thread->thread = pthread_self();
+}
+
+bool virThreadIsSelf(virThreadPtr thread)
+{
+ return pthread_equal(pthread_self(), thread->thread) ? true : false;
+}
+
+/* For debugging use only; this result is not guaranteed unique if
+ * pthread_t is larger than a 64-bit pointer, nor does it always match
+ * the pthread_self() id on Linux. */
+unsigned long long virThreadSelfID(void)
+{
+#if defined(HAVE_SYS_SYSCALL_H) && defined(SYS_gettid)
+ pid_t tid = syscall(SYS_gettid);
+ return tid;
#else
-# error "Either pthreads or Win32 threads are required"
+ union {
+ unsigned long long l;
+ pthread_t t;
+ } u;
+ u.t = pthread_self();
+ return u.l;
#endif
+}
+
+/* For debugging use only; this result is not guaranteed unique if
+ * pthread_t is larger than a 64-bit pointer, nor does it always match
+ * the thread id of virThreadSelfID on Linux. */
+unsigned long long virThreadID(virThreadPtr thread)
+{
+ union {
+ unsigned long long l;
+ pthread_t t;
+ } u;
+ u.t = thread->thread;
+ return u.l;
+}
+
+void virThreadJoin(virThreadPtr thread)
+{
+ pthread_join(thread->thread, NULL);
+}
+
+void virThreadCancel(virThreadPtr thread)
+{
+ pthread_cancel(thread->thread);
+}
+
+int virThreadLocalInit(virThreadLocalPtr l,
+ virThreadLocalCleanup c)
+{
+ int ret;
+ if ((ret = pthread_key_create(&l->key, c)) != 0) {
+ errno = ret;
+ return -1;
+ }
+ return 0;
+}
+
+void *virThreadLocalGet(virThreadLocalPtr l)
+{
+ return pthread_getspecific(l->key);
+}
+
+int virThreadLocalSet(virThreadLocalPtr l, void *val)
+{
+ int err = pthread_setspecific(l->key, val);
+ if (err) {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/util/virthread.h b/src/util/virthread.h
index 7015d60..94476ee 100644
--- a/src/util/virthread.h
+++ b/src/util/virthread.h
@@ -25,24 +25,57 @@
# include "internal.h"
# include "virerror.h"
+# include <pthread.h>
+
typedef struct virMutex virMutex;
typedef virMutex *virMutexPtr;
+struct virMutex {
+ pthread_mutex_t lock;
+};
+
typedef struct virRWLock virRWLock;
typedef virRWLock *virRWLockPtr;
+struct virRWLock {
+ pthread_rwlock_t lock;
+};
+
+
typedef struct virCond virCond;
typedef virCond *virCondPtr;
+struct virCond {
+ pthread_cond_t cond;
+};
+
typedef struct virThreadLocal virThreadLocal;
typedef virThreadLocal *virThreadLocalPtr;
+struct virThreadLocal {
+ pthread_key_t key;
+};
+
typedef struct virThread virThread;
typedef virThread *virThreadPtr;
+struct virThread {
+ pthread_t thread;
+};
+
typedef struct virOnceControl virOnceControl;
typedef virOnceControl *virOnceControlPtr;
+struct virOnceControl {
+ pthread_once_t once;
+};
+
+
+#define VIR_ONCE_CONTROL_INITIALIZER \
+{ \
+ .once = PTHREAD_ONCE_INIT \
+}
+
typedef void (*virOnceFunc)(void);
int virThreadInitialize(void) ATTRIBUTE_RETURN_CHECK;
@@ -121,14 +154,6 @@ int virThreadLocalInit(virThreadLocalPtr l,
void *virThreadLocalGet(virThreadLocalPtr l);
int virThreadLocalSet(virThreadLocalPtr l, void*) ATTRIBUTE_RETURN_CHECK;
-# ifdef WIN32
-# include "virthreadwin32.h"
-# elif defined HAVE_PTHREAD_MUTEXATTR_INIT
-# include "virthreadpthread.h"
-# else
-# error "Either pthreads or Win32 threads are required"
-# endif
-
/**
* VIR_ONCE_GLOBAL_INIT:
diff --git a/src/util/virthreadpthread.c b/src/util/virthreadpthread.c
deleted file mode 100644
index 2efb4c1..0000000
--- a/src/util/virthreadpthread.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * virthreadpthread.c: basic thread synchronization primitives
- *
- * Copyright (C) 2009-2011, 2013 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <
http://www.gnu.org/licenses/>.
- *
- */
-
-#include <config.h>
-
-#include <unistd.h>
-#include <inttypes.h>
-#if HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-
-#include "viralloc.h"
-
-
-/* Nothing special required for pthreads */
-int virThreadInitialize(void)
-{
- return 0;
-}
-
-void virThreadOnExit(void)
-{
-}
-
-int virOnce(virOnceControlPtr once, virOnceFunc init)
-{
- return pthread_once(&once->once, init);
-}
-
-
-int virMutexInit(virMutexPtr m)
-{
- int ret;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
- ret = pthread_mutex_init(&m->lock, &attr);
- pthread_mutexattr_destroy(&attr);
- if (ret != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-int virMutexInitRecursive(virMutexPtr m)
-{
- int ret;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- ret = pthread_mutex_init(&m->lock, &attr);
- pthread_mutexattr_destroy(&attr);
- if (ret != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-void virMutexDestroy(virMutexPtr m)
-{
- pthread_mutex_destroy(&m->lock);
-}
-
-void virMutexLock(virMutexPtr m){
- pthread_mutex_lock(&m->lock);
-}
-
-void virMutexUnlock(virMutexPtr m)
-{
- pthread_mutex_unlock(&m->lock);
-}
-
-
-int virRWLockInit(virRWLockPtr m)
-{
- if (pthread_rwlock_init(&m->lock, NULL) != 0) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-void virRWLockDestroy(virRWLockPtr m)
-{
- pthread_rwlock_destroy(&m->lock);
-}
-
-
-void virRWLockRead(virRWLockPtr m)
-{
- pthread_rwlock_rdlock(&m->lock);
-}
-
-void virRWLockWrite(virRWLockPtr m)
-{
- pthread_rwlock_wrlock(&m->lock);
-}
-
-
-void virRWLockUnlock(virRWLockPtr m)
-{
- pthread_rwlock_unlock(&m->lock);
-}
-
-int virCondInit(virCondPtr c)
-{
- int ret;
- if ((ret = pthread_cond_init(&c->cond, NULL)) != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-int virCondDestroy(virCondPtr c)
-{
- int ret;
- if ((ret = pthread_cond_destroy(&c->cond)) != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-int virCondWait(virCondPtr c, virMutexPtr m)
-{
- int ret;
- if ((ret = pthread_cond_wait(&c->cond, &m->lock)) != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms)
-{
- int ret;
- struct timespec ts;
-
- ts.tv_sec = whenms / 1000;
- ts.tv_nsec = (whenms % 1000) * 1000;
-
- if ((ret = pthread_cond_timedwait(&c->cond, &m->lock, &ts)) != 0)
{
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-void virCondSignal(virCondPtr c)
-{
- pthread_cond_signal(&c->cond);
-}
-
-void virCondBroadcast(virCondPtr c)
-{
- pthread_cond_broadcast(&c->cond);
-}
-
-struct virThreadArgs {
- virThreadFunc func;
- void *opaque;
-};
-
-static void *virThreadHelper(void *data)
-{
- struct virThreadArgs *args = data;
- struct virThreadArgs local = *args;
-
- /* Free args early, rather than tying it up during the entire thread. */
- VIR_FREE(args);
- local.func(local.opaque);
- return NULL;
-}
-
-int virThreadCreate(virThreadPtr thread,
- bool joinable,
- virThreadFunc func,
- void *opaque)
-{
- struct virThreadArgs *args;
- pthread_attr_t attr;
- int ret = -1;
- int err;
-
- if ((err = pthread_attr_init(&attr)) != 0)
- goto cleanup;
- if (VIR_ALLOC_QUIET(args) < 0) {
- err = ENOMEM;
- goto cleanup;
- }
-
- args->func = func;
- args->opaque = opaque;
-
- if (!joinable)
- pthread_attr_setdetachstate(&attr, 1);
-
- err = pthread_create(&thread->thread, &attr, virThreadHelper, args);
- if (err != 0) {
- VIR_FREE(args);
- goto cleanup;
- }
- /* New thread owns 'args' in success case, so don't free */
-
- ret = 0;
-cleanup:
- pthread_attr_destroy(&attr);
- if (ret < 0)
- errno = err;
- return ret;
-}
-
-void virThreadSelf(virThreadPtr thread)
-{
- thread->thread = pthread_self();
-}
-
-bool virThreadIsSelf(virThreadPtr thread)
-{
- return pthread_equal(pthread_self(), thread->thread) ? true : false;
-}
-
-/* For debugging use only; this result is not guaranteed unique if
- * pthread_t is larger than a 64-bit pointer, nor does it always match
- * the pthread_self() id on Linux. */
-unsigned long long virThreadSelfID(void)
-{
-#if defined(HAVE_SYS_SYSCALL_H) && defined(SYS_gettid)
- pid_t tid = syscall(SYS_gettid);
- return tid;
-#else
- union {
- unsigned long long l;
- pthread_t t;
- } u;
- u.t = pthread_self();
- return u.l;
-#endif
-}
-
-/* For debugging use only; this result is not guaranteed unique if
- * pthread_t is larger than a 64-bit pointer, nor does it always match
- * the thread id of virThreadSelfID on Linux. */
-unsigned long long virThreadID(virThreadPtr thread)
-{
- union {
- unsigned long long l;
- pthread_t t;
- } u;
- u.t = thread->thread;
- return u.l;
-}
-
-void virThreadJoin(virThreadPtr thread)
-{
- pthread_join(thread->thread, NULL);
-}
-
-void virThreadCancel(virThreadPtr thread)
-{
- pthread_cancel(thread->thread);
-}
-
-int virThreadLocalInit(virThreadLocalPtr l,
- virThreadLocalCleanup c)
-{
- int ret;
- if ((ret = pthread_key_create(&l->key, c)) != 0) {
- errno = ret;
- return -1;
- }
- return 0;
-}
-
-void *virThreadLocalGet(virThreadLocalPtr l)
-{
- return pthread_getspecific(l->key);
-}
-
-int virThreadLocalSet(virThreadLocalPtr l, void *val)
-{
- int err = pthread_setspecific(l->key, val);
- if (err) {
- errno = err;
- return -1;
- }
- return 0;
-}
diff --git a/src/util/virthreadpthread.h b/src/util/virthreadpthread.h
deleted file mode 100644
index cb607d0..0000000
--- a/src/util/virthreadpthread.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * virthreadpthread.c: basic thread synchronization primitives
- *
- * Copyright (C) 2009, 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <
http://www.gnu.org/licenses/>.
- *
- */
-
-#include "internal.h"
-
-#include <pthread.h>
-
-struct virMutex {
- pthread_mutex_t lock;
-};
-
-struct virRWLock {
- pthread_rwlock_t lock;
-};
-
-struct virCond {
- pthread_cond_t cond;
-};
-
-struct virThread {
- pthread_t thread;
-};
-
-struct virThreadLocal {
- pthread_key_t key;
-};
-
-struct virOnceControl {
- pthread_once_t once;
-};
-
-#define VIR_ONCE_CONTROL_INITIALIZER \
-{ \
- .once = PTHREAD_ONCE_INIT \
-}
diff --git a/src/util/virthreadwin32.c b/src/util/virthreadwin32.c
deleted file mode 100644
index 5d6277f..0000000
--- a/src/util/virthreadwin32.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * virthreadwin32.c: basic thread synchronization primitives
- *
- * Copyright (C) 2009-2011, 2013 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <
http://www.gnu.org/licenses/>.
- *
- */
-
-#include <config.h>
-
-#include <process.h>
-
-#include "viralloc.h"
-
-#define VIR_FROM_THIS VIR_FROM_NONE
-
-struct virThreadLocalData {
- DWORD key;
- virThreadLocalCleanup cleanup;
-};
-typedef struct virThreadLocalData virThreadLocalData;
-typedef virThreadLocalData *virThreadLocalDataPtr;
-
-virMutex virThreadLocalLock;
-size_t virThreadLocalCount = 0;
-virThreadLocalDataPtr virThreadLocalList = NULL;
-DWORD selfkey;
-
-virThreadLocal virCondEvent;
-
-void virCondEventCleanup(void *data);
-
-int virThreadInitialize(void)
-{
- if (virMutexInit(&virThreadLocalLock) < 0)
- return -1;
- if (virThreadLocalInit(&virCondEvent, virCondEventCleanup) < 0)
- return -1;
- if ((selfkey = TlsAlloc()) == TLS_OUT_OF_INDEXES)
- return -1;
- return 0;
-}
-
-void virThreadOnExit(void)
-{
- size_t i;
- virMutexLock(&virThreadLocalLock);
- for (i = 0; i < virThreadLocalCount; i++) {
- if (virThreadLocalList[i].cleanup) {
- void *data = TlsGetValue(virThreadLocalList[i].key);
- if (data) {
- TlsSetValue(virThreadLocalList[i].key, NULL);
-
- (virThreadLocalList[i].cleanup)(data);
- }
- }
- }
- virMutexUnlock(&virThreadLocalLock);
-}
-
-int virOnce(virOnceControlPtr once, virOnceFunc func)
-{
- if (!once->complete) {
- if (InterlockedIncrement(&once->init) == 1) {
- /* We're the first thread. */
- func();
- once->complete = 1;
- } else {
- /* We're a later thread. Decrement the init counter back
- * to avoid overflow, then yield until the first thread
- * marks that the function is complete. It is rare that
- * multiple threads will be waiting here, and since each
- * thread is yielding except the first, we should get out
- * soon enough. */
- InterlockedDecrement(&once->init);
- while (!once->complete)
- Sleep(0);
- }
- }
- return 0;
-}
-
-int virMutexInit(virMutexPtr m)
-{
- return virMutexInitRecursive(m);
-}
-
-int virMutexInitRecursive(virMutexPtr m)
-{
- if (!(m->lock = CreateMutex(NULL, FALSE, NULL))) {
- errno = ESRCH;
- return -1;
- }
- return 0;
-}
-
-void virMutexDestroy(virMutexPtr m)
-{
- CloseHandle(m->lock);
-}
-
-void virMutexLock(virMutexPtr m)
-{
- WaitForSingleObject(m->lock, INFINITE);
-}
-
-void virMutexUnlock(virMutexPtr m)
-{
- ReleaseMutex(m->lock);
-}
-
-
-
-int virCondInit(virCondPtr c)
-{
- c->waiters = NULL;
- if (virMutexInit(&c->lock) < 0)
- return -1;
- return 0;
-}
-
-int virCondDestroy(virCondPtr c)
-{
- if (c->waiters) {
- errno = EINVAL;
- return -1;
- }
- virMutexDestroy(&c->lock);
- return 0;
-}
-
-void virCondEventCleanup(void *data)
-{
- HANDLE event = data;
- CloseHandle(event);
-}
-
-int virCondWait(virCondPtr c, virMutexPtr m)
-{
- HANDLE event = virThreadLocalGet(&virCondEvent);
-
- if (!event) {
- event = CreateEvent(0, FALSE, FALSE, NULL);
- if (!event) {
- return -1;
- }
- if (virThreadLocalSet(&virCondEvent, event) < 0) {
- CloseHandle(event);
- return -1;
- }
- }
-
- virMutexLock(&c->lock);
-
- if (VIR_REALLOC_N(c->waiters, c->nwaiters + 1) < 0) {
- virMutexUnlock(&c->lock);
- return -1;
- }
- c->waiters[c->nwaiters] = event;
- c->nwaiters++;
-
- virMutexUnlock(&c->lock);
-
- virMutexUnlock(m);
-
- if (WaitForSingleObject(event, INFINITE) == WAIT_FAILED) {
- virMutexLock(m);
- errno = EINVAL;
- return -1;
- }
-
- virMutexLock(m);
- return 0;
-}
-
-int virCondWaitUntil(virCondPtr c ATTRIBUTE_UNUSED,
- virMutexPtr m ATTRIBUTE_UNUSED,
- unsigned long long whenms ATTRIBUTE_UNUSED)
-{
- /* FIXME: this function is currently only used by the QEMU driver that
- * is not compiled on Windows, so it's okay for now to just
- * miss an implementation */
- return -1;
-}
-
-void virCondSignal(virCondPtr c)
-{
- virMutexLock(&c->lock);
-
- if (c->nwaiters) {
- HANDLE event = c->waiters[0];
- if (c->nwaiters > 1)
- memmove(c->waiters,
- c->waiters + 1,
- sizeof(c->waiters[0]) * (c->nwaiters-1));
- if (VIR_REALLOC_N(c->waiters, c->nwaiters - 1) < 0) {
- ;
- }
- c->nwaiters--;
- SetEvent(event);
- }
-
- virMutexUnlock(&c->lock);
-}
-
-void virCondBroadcast(virCondPtr c)
-{
- virMutexLock(&c->lock);
-
- if (c->nwaiters) {
- size_t i;
- for (i = 0; i < c->nwaiters; i++) {
- HANDLE event = c->waiters[i];
- SetEvent(event);
- }
- VIR_FREE(c->waiters);
- c->nwaiters = 0;
- }
-
- virMutexUnlock(&c->lock);
-}
-
-
-struct virThreadArgs {
- virThreadFunc func;
- void *opaque;
-};
-
-static void virThreadHelperDaemon(void *data)
-{
- struct virThreadArgs *args = data;
- virThread self;
- HANDLE handle = GetCurrentThread();
- HANDLE process = GetCurrentProcess();
-
- self.joinable = false;
- DuplicateHandle(process, handle, process,
- &self.thread, 0, FALSE,
- DUPLICATE_SAME_ACCESS);
- TlsSetValue(selfkey, &self);
-
- args->func(args->opaque);
-
- TlsSetValue(selfkey, NULL);
- CloseHandle(self.thread);
-
- VIR_FREE(args);
-}
-
-static unsigned int __stdcall virThreadHelperJoinable(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);
-
- VIR_FREE(args);
- return 0;
-}
-
-int virThreadCreate(virThreadPtr thread,
- bool joinable,
- virThreadFunc func,
- void *opaque)
-{
- struct virThreadArgs *args;
- uintptr_t ret;
-
- if (VIR_ALLOC(args) < 0)
- return -1;
-
- args->func = func;
- args->opaque = opaque;
-
- thread->joinable = joinable;
- if (joinable) {
- ret = _beginthreadex(NULL, 0,
- virThreadHelperJoinable,
- args, 0, NULL);
- if (ret == 0)
- return -1;
- } else {
- ret = _beginthread(virThreadHelperDaemon,
- 0, args);
- if (ret == -1L)
- return -1;
- }
-
- thread->thread = (HANDLE)ret;
-
- return 0;
-}
-
-void virThreadSelf(virThreadPtr thread)
-{
- virThreadPtr self = TlsGetValue(selfkey);
-
- if (self == NULL) {
- /* called on a thread not created by virThreadCreate, e.g. the main thread */
- thread->thread = 0;
- thread->joinable = false;
- } else {
- thread->thread = self->thread;
- thread->joinable = self->joinable;
- }
-}
-
-bool virThreadIsSelf(virThreadPtr thread)
-{
- virThread self;
- virThreadSelf(&self);
- return self.thread == thread->thread ? true : false;
-}
-
-/* For debugging use only; see comments in virthreadpthread.c. */
-unsigned long long virThreadSelfID(void)
-{
- return GetCurrentThreadId();
-}
-
-/* For debugging use only; see comments in virthreadpthread.c. */
-unsigned long long virThreadID(virThreadPtr thread)
-{
- return (intptr_t)thread->thread;
-}
-
-
-void virThreadJoin(virThreadPtr thread)
-{
- if (thread->joinable) {
- WaitForSingleObject(thread->thread, INFINITE);
- CloseHandle(thread->thread);
- thread->thread = 0;
- thread->joinable = false;
- }
-}
-
-void virThreadCancel(virThreadPtr thread ATTRIBUTE_UNUSED)
-{}
-
-int virThreadLocalInit(virThreadLocalPtr l,
- virThreadLocalCleanup c)
-{
- if ((l->key = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
- errno = ESRCH;
- return -1;
- }
- TlsSetValue(l->key, NULL);
-
- if (c) {
- virMutexLock(&virThreadLocalLock);
- if (VIR_REALLOC_N(virThreadLocalList,
- virThreadLocalCount + 1) < 0)
- return -1;
- virThreadLocalList[virThreadLocalCount].key = l->key;
- virThreadLocalList[virThreadLocalCount].cleanup = c;
- virThreadLocalCount++;
- virMutexUnlock(&virThreadLocalLock);
- }
-
- return 0;
-}
-
-void *virThreadLocalGet(virThreadLocalPtr l)
-{
- return TlsGetValue(l->key);
-}
-
-int virThreadLocalSet(virThreadLocalPtr l, void *val)
-{
- return TlsSetValue(l->key, val) == 0 ? -1 : 0;
-}
diff --git a/src/util/virthreadwin32.h b/src/util/virthreadwin32.h
deleted file mode 100644
index 645031b..0000000
--- a/src/util/virthreadwin32.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * virthreadwin32.h basic thread synchronization primitives
- *
- * Copyright (C) 2009, 2011-2012 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <
http://www.gnu.org/licenses/>.
- *
- */
-
-#include "internal.h"
-
-#ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
-#endif
-#include <windows.h>
-
-struct virMutex {
- HANDLE lock;
-};
-
-struct virCond {
- virMutex lock;
- size_t nwaiters;
- HANDLE *waiters;
-};
-
-struct virThread {
- HANDLE thread;
- bool joinable;
-};
-
-struct virThreadLocal {
- DWORD key;
-};
-
-struct virOnceControl {
- volatile long init; /* 0 at startup, > 0 if init has started */
- volatile long complete; /* 0 until first thread completes callback */
-};
-
-#define VIR_ONCE_CONTROL_INITIALIZER { 0, 0 }
--
1.8.4.2