From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
daemon/libvirtd.c | 1 -
daemon/libvirtd.h | 2 +-
src/Makefile.am | 8 +-
src/conf/device_conf.h | 2 +-
src/conf/domain_conf.h | 2 +-
src/conf/interface_conf.h | 2 +-
src/conf/network_conf.h | 2 +-
src/conf/node_device_conf.h | 2 +-
src/conf/storage_conf.h | 2 +-
src/conf/virconsole.c | 2 +-
src/datatypes.h | 2 +-
src/libvirt.c | 2 +-
src/locking/lock_daemon.h | 2 +-
src/lxc/lxc_conf.h | 2 +-
src/lxc/lxc_monitor.c | 2 +-
src/nwfilter/nwfilter_learnipaddr.c | 2 +-
src/openvz/openvz_conf.h | 2 +-
src/parallels/parallels_utils.h | 2 +-
src/qemu/qemu_conf.h | 2 +-
src/qemu/qemu_domain.h | 2 +-
src/rpc/virkeepalive.c | 2 +-
src/rpc/virnetclient.c | 2 +-
src/rpc/virnetclientprogram.c | 2 +-
src/rpc/virnetclientstream.c | 2 +-
src/rpc/virnetsaslcontext.c | 2 +-
src/rpc/virnetserver.c | 2 +-
src/rpc/virnetserverclient.c | 2 +-
src/rpc/virnetserverprogram.c | 2 +-
src/rpc/virnetserverservice.c | 2 +-
src/rpc/virnetsocket.c | 2 +-
src/rpc/virnetsshsession.c | 2 +-
src/rpc/virnettlscontext.c | 2 +-
src/secret/secret_driver.c | 2 +-
src/test/test_driver.c | 2 +-
src/uml/uml_conf.h | 2 +-
src/util/iohelper.c | 2 +-
src/util/threads-pthread.c | 263 ------------------------
src/util/threads-pthread.h | 49 -----
src/util/threads-win32.c | 392 ------------------------------------
src/util/threads-win32.h | 53 -----
src/util/threads.c | 34 ----
src/util/threads.h | 166 ---------------
src/util/util.c | 2 +-
src/util/virdbus.c | 2 +-
src/util/virebtables.c | 2 +-
src/util/vireventpoll.c | 2 +-
src/util/viriptables.c | 2 +-
src/util/virlockspace.c | 2 +-
src/util/virlog.c | 2 +-
src/util/virnetlink.c | 2 +-
src/util/virnodesuspend.c | 2 +-
src/util/virobject.c | 2 +-
src/util/virrandom.c | 2 +-
src/util/virterror.c | 2 +-
src/util/virthread.c | 34 ++++
src/util/virthread.h | 166 +++++++++++++++
src/util/virthreadpool.c | 2 +-
src/util/virthreadpthread.c | 263 ++++++++++++++++++++++++
src/util/virthreadpthread.h | 49 +++++
src/util/virthreadwin32.c | 392 ++++++++++++++++++++++++++++++++++++
src/util/virthreadwin32.h | 53 +++++
src/vmware/vmware_conf.h | 2 +-
src/xen/xen_hypervisor.c | 2 +-
tests/eventtest.c | 2 +-
tests/nwfilterxml2xmltest.c | 2 +-
tests/qemumonitorjsontest.c | 2 +-
tests/qemumonitortestutils.c | 2 +-
tests/testutils.c | 2 +-
tests/viratomictest.c | 2 +-
tools/console.c | 2 +-
tools/virsh.c | 2 +-
tools/virsh.h | 2 +-
72 files changed, 1019 insertions(+), 1020 deletions(-)
delete mode 100644 src/util/threads-pthread.c
delete mode 100644 src/util/threads-pthread.h
delete mode 100644 src/util/threads-win32.c
delete mode 100644 src/util/threads-win32.h
delete mode 100644 src/util/threads.c
delete mode 100644 src/util/threads.h
create mode 100644 src/util/virthread.c
create mode 100644 src/util/virthread.h
create mode 100644 src/util/virthreadpthread.c
create mode 100644 src/util/virthreadpthread.h
create mode 100644 src/util/virthreadwin32.c
create mode 100644 src/util/virthreadwin32.h
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 903f8c2..dc1d2c5 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -50,7 +50,6 @@
#include "virconf.h"
#include "virnetlink.h"
#include "virnetserver.h"
-#include "threads.h"
#include "remote.h"
#include "remote_driver.h"
#include "virhooks.h"
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index b04cc71..69a77ea 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -34,7 +34,7 @@
# include "remote_protocol.h"
# include "qemu_protocol.h"
# include "virlog.h"
-# include "threads.h"
+# include "virthread.h"
# if HAVE_SASL
# include "virnetsaslcontext.h"
# endif
diff --git a/src/Makefile.am b/src/Makefile.am
index e74a3a3..d8d96f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,9 +53,6 @@ augeastest_DATA =
# These files are not related to driver APIs. Simply generic
# helper APIs for various purposes
UTIL_SOURCES = \
- util/threads.c util/threads.h \
- util/threads-pthread.h \
- util/threads-win32.h \
util/uuid.c util/uuid.h \
util/util.c util/util.h \
util/viralloc.c util/viralloc.h \
@@ -85,6 +82,9 @@ UTIL_SOURCES = \
util/virstatslinux.c util/virstatslinux.h \
util/virstoragefile.c util/virstoragefile.h \
util/virsysinfo.c util/virsysinfo.h \
+ util/virthread.c util/virthread.h \
+ util/virthreadpthread.h \
+ util/virthreadwin32.h \
util/virthreadpool.c util/virthreadpool.h \
util/virtypedparam.c util/virtypedparam.h \
util/xml.c util/xml.h \
@@ -125,7 +125,7 @@ $(srcdir)/util/virkeymaps.h: $(srcdir)/util/keymaps.csv \
$(srcdir)/util/virkeycode-mapgen.py
$(AM_V_GEN)$(PYTHON) $(srcdir)/util/virkeycode-mapgen.py <$(srcdir)/util/keymaps.csv
>$@
-EXTRA_DIST += util/threads-pthread.c util/threads-win32.c
+EXTRA_DIST += util/virthreadpthread.c util/virthreadwin32.c
# Internal generic driver infrastructure
NODE_INFO_SOURCES = nodeinfo.h nodeinfo.c
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index 09d6be9..c1bf096 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -29,7 +29,7 @@
# include "internal.h"
# include "util.h"
-# include "threads.h"
+# include "virthread.h"
# include "virbuffer.h"
enum virDeviceAddressPciMulti {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 718c6a9..56aece2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -33,7 +33,7 @@
# include "storage_encryption_conf.h"
# include "cpu_conf.h"
# include "util.h"
-# include "threads.h"
+# include "virthread.h"
# include "virhash.h"
# include "virsocketaddr.h"
# include "nwfilter_params.h"
diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h
index 1749629..d6f98f1 100644
--- a/src/conf/interface_conf.h
+++ b/src/conf/interface_conf.h
@@ -30,7 +30,7 @@
# include "internal.h"
# include "util.h"
-# include "threads.h"
+# include "virthread.h"
/* There is currently 3 types of interfaces */
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 4d70fe6..4c634ed 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -31,7 +31,7 @@
# include <libxml/xpath.h>
# include "internal.h"
-# include "threads.h"
+# include "virthread.h"
# include "virsocketaddr.h"
# include "virnetdevbandwidth.h"
# include "virnetdevvportprofile.h"
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index e394042..9860f67 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -27,7 +27,7 @@
# include "internal.h"
# include "util.h"
-# include "threads.h"
+# include "virthread.h"
# include <libxml/tree.h>
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 743b768..573c3db 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -27,7 +27,7 @@
# include "internal.h"
# include "util.h"
# include "storage_encryption_conf.h"
-# include "threads.h"
+# include "virthread.h"
# include <libxml/tree.h>
diff --git a/src/conf/virconsole.c b/src/conf/virconsole.c
index 757573d..515c5fa 100644
--- a/src/conf/virconsole.c
+++ b/src/conf/virconsole.c
@@ -31,7 +31,7 @@
#include "virhash.h"
#include "fdstream.h"
#include "internal.h"
-#include "threads.h"
+#include "virthread.h"
#include "viralloc.h"
#include "virpidfile.h"
#include "virlog.h"
diff --git a/src/datatypes.h b/src/datatypes.h
index 55f97ed..a1dfc1e 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -25,7 +25,7 @@
# include "internal.h"
# include "driver.h"
-# include "threads.h"
+# include "virthread.h"
# include "virobject.h"
extern virClassPtr virConnectClass;
diff --git a/src/libvirt.c b/src/libvirt.c
index ed7dcae..5654d53 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -59,7 +59,7 @@
#include "vircommand.h"
#include "virrandom.h"
#include "viruri.h"
-#include "threads.h"
+#include "virthread.h"
#ifdef WITH_TEST
# include "test/test_driver.h"
diff --git a/src/locking/lock_daemon.h b/src/locking/lock_daemon.h
index 619f8f2..da62edc 100644
--- a/src/locking/lock_daemon.h
+++ b/src/locking/lock_daemon.h
@@ -24,7 +24,7 @@
# define __VIR_LOCK_DAEMON_H__
# include "virlockspace.h"
-# include "threads.h"
+# include "virthread.h"
typedef struct _virLockDaemon virLockDaemon;
typedef virLockDaemon *virLockDaemonPtr;
diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h
index c02966f..b0b7711 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -31,7 +31,7 @@
# include "domain_conf.h"
# include "domain_event.h"
# include "capabilities.h"
-# include "threads.h"
+# include "virthread.h"
# include "vircgroup.h"
# include "security/security_manager.h"
# include "configmake.h"
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
index 90637eb..b0da21f 100644
--- a/src/lxc/lxc_monitor.c
+++ b/src/lxc/lxc_monitor.c
@@ -29,7 +29,7 @@
#include "virterror_internal.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#include "rpc/virnetclient.h"
#define VIR_FROM_THIS VIR_FROM_LXC
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 8c4bbcf..442cc83 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -47,7 +47,7 @@
#include "datatypes.h"
#include "virnetdev.h"
#include "virterror_internal.h"
-#include "threads.h"
+#include "virthread.h"
#include "conf/nwfilter_params.h"
#include "conf/domain_conf.h"
#include "nwfilter_gentech_driver.h"
diff --git a/src/openvz/openvz_conf.h b/src/openvz/openvz_conf.h
index 3eb2b3e..c1007f0 100644
--- a/src/openvz/openvz_conf.h
+++ b/src/openvz/openvz_conf.h
@@ -31,7 +31,7 @@
# include "internal.h"
# include "domain_conf.h"
-# include "threads.h"
+# include "virthread.h"
/* OpenVZ commands - Replace with wrapper scripts later? */
diff --git a/src/parallels/parallels_utils.h b/src/parallels/parallels_utils.h
index 7c31707..cf006e8 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -24,11 +24,11 @@
# define PARALLELS_UTILS_H
# include "driver.h"
-# include "util/threads.h"
# include "conf/domain_conf.h"
# include "conf/storage_conf.h"
# include "conf/domain_event.h"
# include "conf/network_conf.h"
+# include "virthread.h"
# include "virjson.h"
# define parallelsParseError() \
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 0d4816e..1aa56cc 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -32,7 +32,7 @@
# include "network_conf.h"
# include "domain_conf.h"
# include "domain_event.h"
-# include "threads.h"
+# include "virthread.h"
# include "security/security_manager.h"
# include "vircgroup.h"
# include "virpci.h"
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 11670b9..00648cf 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -24,7 +24,7 @@
#ifndef __QEMU_DOMAIN_H__
# define __QEMU_DOMAIN_H__
-# include "threads.h"
+# include "virthread.h"
# include "domain_conf.h"
# include "snapshot_conf.h"
# include "qemu_monitor.h"
diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c
index 91af315..5c14e14 100644
--- a/src/rpc/virkeepalive.c
+++ b/src/rpc/virkeepalive.c
@@ -23,7 +23,7 @@
#include <config.h>
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virfile.h"
#include "virlog.h"
#include "util.h"
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index b4fe4d9..85787f0 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -31,7 +31,7 @@
#include "virnetsocket.h"
#include "virkeepalive.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virfile.h"
#include "virlog.h"
#include "util.h"
diff --git a/src/rpc/virnetclientprogram.c b/src/rpc/virnetclientprogram.c
index 7396971..00948e0 100644
--- a/src/rpc/virnetclientprogram.c
+++ b/src/rpc/virnetclientprogram.c
@@ -33,7 +33,7 @@
#include "virlog.h"
#include "util.h"
#include "virfile.h"
-#include "threads.h"
+#include "virthread.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c
index 4877b0c..7e1f9c7 100644
--- a/src/rpc/virnetclientstream.c
+++ b/src/rpc/virnetclientstream.c
@@ -27,7 +27,7 @@
#include "viralloc.h"
#include "virterror_internal.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetsaslcontext.c b/src/rpc/virnetsaslcontext.c
index adc4f1e..cd30f4d 100644
--- a/src/rpc/virnetsaslcontext.c
+++ b/src/rpc/virnetsaslcontext.c
@@ -27,7 +27,7 @@
#include "virterror_internal.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virlog.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 26ceb0c..b48af5e 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -31,7 +31,7 @@
#include "virlog.h"
#include "viralloc.h"
#include "virterror_internal.h"
-#include "threads.h"
+#include "virthread.h"
#include "virthreadpool.h"
#include "util.h"
#include "virfile.h"
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 7f028b8..f1eb69b 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -32,7 +32,7 @@
#include "virlog.h"
#include "virterror_internal.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virkeepalive.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetserverprogram.c b/src/rpc/virnetserverprogram.c
index 287282e..a8f875c 100644
--- a/src/rpc/virnetserverprogram.c
+++ b/src/rpc/virnetserverprogram.c
@@ -30,7 +30,7 @@
#include "virterror_internal.h"
#include "virlog.h"
#include "virfile.h"
-#include "threads.h"
+#include "virthread.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c
index 92b5cef..9992983 100644
--- a/src/rpc/virnetserverservice.c
+++ b/src/rpc/virnetserverservice.c
@@ -27,7 +27,7 @@
#include "viralloc.h"
#include "virterror_internal.h"
-#include "threads.h"
+#include "virthread.h"
#define VIR_FROM_THIS VIR_FROM_RPC
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 8c62a2a..442850a 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -46,7 +46,7 @@
#include "virterror_internal.h"
#include "virlog.h"
#include "virfile.h"
-#include "threads.h"
+#include "virthread.h"
#include "virprocess.h"
#include "passfd.h"
diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c
index 8a7d5f9..663b7cd 100644
--- a/src/rpc/virnetsshsession.c
+++ b/src/rpc/virnetsshsession.c
@@ -30,7 +30,7 @@
#include "viralloc.h"
#include "virlog.h"
#include "configmake.h"
-#include "threads.h"
+#include "virthread.h"
#include "util.h"
#include "virterror_internal.h"
#include "virobject.h"
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index d9354e0..1ff40cf 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -34,7 +34,7 @@
#include "virterror_internal.h"
#include "util.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#include "configmake.h"
#define DH_BITS 1024
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index fb2024b..672ff54 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -36,7 +36,7 @@
#include "viralloc.h"
#include "secret_conf.h"
#include "secret_driver.h"
-#include "threads.h"
+#include "virthread.h"
#include "util.h"
#include "uuid.h"
#include "virterror_internal.h"
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 3abd289..185bb3b 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -47,7 +47,7 @@
#include "storage_conf.h"
#include "node_device_conf.h"
#include "xml.h"
-#include "threads.h"
+#include "virthread.h"
#include "virlog.h"
#include "virfile.h"
#include "virtypedparam.h"
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h
index 09a0305..dfa168e 100644
--- a/src/uml/uml_conf.h
+++ b/src/uml/uml_conf.h
@@ -30,7 +30,7 @@
# include "domain_conf.h"
# include "domain_event.h"
# include "virterror_internal.h"
-# include "threads.h"
+# include "virthread.h"
# include "vircommand.h"
# include "virhash.h"
diff --git a/src/util/iohelper.c b/src/util/iohelper.c
index 1b16d5c..dcb5c14 100644
--- a/src/util/iohelper.c
+++ b/src/util/iohelper.c
@@ -34,7 +34,7 @@
#include <stdlib.h>
#include "util.h"
-#include "threads.h"
+#include "virthread.h"
#include "virfile.h"
#include "viralloc.h"
#include "virterror_internal.h"
diff --git a/src/util/threads-pthread.c b/src/util/threads-pthread.c
deleted file mode 100644
index 37d8902..0000000
--- a/src/util/threads-pthread.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * threads-pthread.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 <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 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(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 on BSD
- * systems when pthread_t is a 64-bit pointer. */
-int virThreadSelfID(void)
-{
-#if defined(HAVE_SYS_SYSCALL_H) && defined(SYS_gettid)
- pid_t tid;
- tid = syscall(SYS_gettid);
- return (int)tid;
-#else
- return (int)(intptr_t)(void *)pthread_self();
-#endif
-}
-
-/* For debugging use only; this result is not guaranteed unique on BSD
- * systems when pthread_t is a 64-bit pointer, nor does it match the
- * thread id of virThreadSelfID on Linux. */
-int virThreadID(virThreadPtr thread)
-{
- return (int)(uintptr_t)thread->thread;
-}
-
-void virThreadJoin(virThreadPtr thread)
-{
- pthread_join(thread->thread, NULL);
-}
-
-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/threads-pthread.h b/src/util/threads-pthread.h
deleted file mode 100644
index ddaedb7..0000000
--- a/src/util/threads-pthread.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * threads.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 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/threads-win32.c b/src/util/threads-win32.c
deleted file mode 100644
index c9f16c1..0000000
--- a/src/util/threads-win32.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * threads-win32.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 <config.h>
-
-#include <process.h>
-
-#include "viralloc.h"
-
-struct virThreadLocalData {
- DWORD key;
- virThreadLocalCleanup cleanup;
-};
-typedef struct virThreadLocalData virThreadLocalData;
-typedef virThreadLocalData *virThreadLocalDataPtr;
-
-virMutex virThreadLocalLock;
-unsigned int 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)
-{
- unsigned int 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) {
- unsigned int 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 threads-pthread.c. */
-int virThreadSelfID(void)
-{
- return (int)GetCurrentThreadId();
-}
-
-/* For debugging use only; see comments in threads-pthread.c. */
-int 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;
- }
-}
-
-
-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/threads-win32.h b/src/util/threads-win32.h
deleted file mode 100644
index 07a1bf5..0000000
--- a/src/util/threads-win32.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * threads-win32.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;
- unsigned int 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 }
diff --git a/src/util/threads.c b/src/util/threads.c
deleted file mode 100644
index d0d5b83..0000000
--- a/src/util/threads.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * threads.c: basic thread synchronization primitives
- *
- * Copyright (C) 2009-2010 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 "threads.h"
-
-/* On mingw, we prefer native threading over the sometimes-broken
- * pthreads-win32 library wrapper. */
-#ifdef WIN32
-# include "threads-win32.c"
-#elif defined HAVE_PTHREAD_MUTEXATTR_INIT
-# include "threads-pthread.c"
-#else
-# error "Either pthreads or Win32 threads are required"
-#endif
diff --git a/src/util/threads.h b/src/util/threads.h
deleted file mode 100644
index 9761764..0000000
--- a/src/util/threads.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * threads.h: 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/>.
- *
- */
-
-#ifndef __THREADS_H_
-# define __THREADS_H_
-
-# include "internal.h"
-
-typedef struct virMutex virMutex;
-typedef virMutex *virMutexPtr;
-
-typedef struct virCond virCond;
-typedef virCond *virCondPtr;
-
-typedef struct virThreadLocal virThreadLocal;
-typedef virThreadLocal *virThreadLocalPtr;
-
-typedef struct virThread virThread;
-typedef virThread *virThreadPtr;
-
-typedef struct virOnceControl virOnceControl;
-typedef virOnceControl *virOnceControlPtr;
-
-typedef void (*virOnceFunc)(void);
-
-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);
-
-/* These next two functions are for debugging only, since they are not
- * guaranteed to give unique values for distinct threads on all
- * architectures, nor are the two functions guaranteed to give the same
- * value for the same thread. */
-int virThreadSelfID(void);
-int virThreadID(virThreadPtr thread);
-
-/* Static initialization of mutexes is not possible, so we instead
- * provide for guaranteed one-time initialization via a callback
- * function. Usage:
- * static virOnceControl once = VIR_ONCE_CONTROL_INITIALIZER;
- * static void initializer(void) { ... }
- * void myfunc()
- * {
- * if (virOnce(&once, initializer) < 0)
- * goto error;
- * ...now guaranteed that initializer has completed exactly once
- * }
- */
-int virOnce(virOnceControlPtr once, virOnceFunc init)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-
-int virMutexInit(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
-int virMutexInitRecursive(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
-void virMutexDestroy(virMutexPtr m);
-
-void virMutexLock(virMutexPtr m);
-void virMutexUnlock(virMutexPtr m);
-
-
-
-int virCondInit(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
-int virCondDestroy(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
-
-/* virCondWait, virCondWaitUntil:
- * These functions can return without the associated predicate
- * changing value. Therefore in nearly all cases they
- * should be enclosed in a while loop that checks the predicate.
- */
-int virCondWait(virCondPtr c, virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
-int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms)
ATTRIBUTE_RETURN_CHECK;
-
-void virCondSignal(virCondPtr c);
-void virCondBroadcast(virCondPtr c);
-
-
-typedef void (*virThreadLocalCleanup)(void *);
-int virThreadLocalInit(virThreadLocalPtr l,
- virThreadLocalCleanup c) ATTRIBUTE_RETURN_CHECK;
-void *virThreadLocalGet(virThreadLocalPtr l);
-int virThreadLocalSet(virThreadLocalPtr l, void*) ATTRIBUTE_RETURN_CHECK;
-
-# ifdef WIN32
-# include "threads-win32.h"
-# elif defined HAVE_PTHREAD_MUTEXATTR_INIT
-# include "threads-pthread.h"
-# else
-# error "Either pthreads or Win32 threads are required"
-# endif
-
-
-/**
- * VIR_ONCE_GLOBAL_INIT:
- * classname: base classname
- *
- * This macro simplifies the setup of a one-time only
- * global file initializer.
- *
- * Assuming a class called "virMyObject", and a method
- * implemented like:
- *
- * int virMyObjectOnceInit(void) {
- * ...do init tasks...
- * }
- *
- * Then invoking the macro:
- *
- * VIR_ONCE_GLOBAL_INIT(virMyObject)
- *
- * Will create a method
- *
- * int virMyObjectInitialize(void);
- *
- * Which will ensure that 'virMyObjectOnceInit' is
- * guaranteed to be invoked exactly once.
- */
-# define VIR_ONCE_GLOBAL_INIT(classname) \
- static virOnceControl classname ## OnceControl = VIR_ONCE_CONTROL_INITIALIZER; \
- static virErrorPtr classname ## OnceError = NULL; \
- \
- static void classname ## Once(void) \
- { \
- if (classname ## OnceInit() < 0) \
- classname ## OnceError = virSaveLastError(); \
- } \
- \
- static int classname ## Initialize(void) \
- { \
- if (virOnce(&classname ## OnceControl, classname ## Once) < 0) \
- return -1; \
- \
- if (classname ## OnceError) { \
- virSetError(classname ## OnceError); \
- return -1; \
- } \
- \
- return 0; \
- }
-
-#endif
diff --git a/src/util/util.c b/src/util/util.c
index 5d32995..c7d4aa5 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -81,7 +81,7 @@
#include "util.h"
#include "virstoragefile.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "verify.h"
#include "virfile.h"
#include "vircommand.h"
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 34c46b2..f45074c 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -25,7 +25,7 @@
#include "viralloc.h"
#include "virterror_internal.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#define VIR_FROM_THIS VIR_FROM_DBUS
diff --git a/src/util/virebtables.c b/src/util/virebtables.c
index 1beb085..edf4956 100644
--- a/src/util/virebtables.c
+++ b/src/util/virebtables.c
@@ -45,7 +45,7 @@
#include "viralloc.h"
#include "virterror_internal.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#if HAVE_FIREWALLD
static char *firewall_cmd_path = NULL;
diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c
index cf4dc41..1180fda 100644
--- a/src/util/vireventpoll.c
+++ b/src/util/vireventpoll.c
@@ -31,7 +31,7 @@
#include <unistd.h>
#include <fcntl.h>
-#include "threads.h"
+#include "virthread.h"
#include "virlog.h"
#include "vireventpoll.h"
#include "viralloc.h"
diff --git a/src/util/viriptables.c b/src/util/viriptables.c
index 178580d..eb8acf5 100644
--- a/src/util/viriptables.c
+++ b/src/util/viriptables.c
@@ -43,7 +43,7 @@
#include "viralloc.h"
#include "virterror_internal.h"
#include "virlog.h"
-#include "threads.h"
+#include "virthread.h"
#if HAVE_FIREWALLD
static char *firewall_cmd_path = NULL;
diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c
index 509b162..961e171 100644
--- a/src/util/virlockspace.c
+++ b/src/util/virlockspace.c
@@ -28,7 +28,7 @@
#include "util.h"
#include "virfile.h"
#include "virhash.h"
-#include "threads.h"
+#include "virthread.h"
#include <fcntl.h>
#include <unistd.h>
diff --git a/src/util/virlog.c b/src/util/virlog.c
index cb15a22..0c6c13a 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -45,7 +45,7 @@
#include "viralloc.h"
#include "util.h"
#include "virbuffer.h"
-#include "threads.h"
+#include "virthread.h"
#include "virfile.h"
#include "virtime.h"
#include "intprops.h"
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index b132d9a..fdd4c0d 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -38,7 +38,7 @@
#include "virnetlink.h"
#include "virlog.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virmacaddr.h"
#include "virterror_internal.h"
diff --git a/src/util/virnodesuspend.c b/src/util/virnodesuspend.c
index 1528cf1..878be1d 100644
--- a/src/util/virnodesuspend.c
+++ b/src/util/virnodesuspend.c
@@ -23,7 +23,7 @@
#include "virnodesuspend.h"
#include "vircommand.h"
-#include "threads.h"
+#include "virthread.h"
#include "datatypes.h"
#include "viralloc.h"
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 5cdd2e8..aca6182 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -22,7 +22,7 @@
#include <config.h>
#include "virobject.h"
-#include "threads.h"
+#include "virthread.h"
#include "viralloc.h"
#include "viratomic.h"
#include "virterror_internal.h"
diff --git a/src/util/virrandom.c b/src/util/virrandom.c
index c24bf3b..1dd96cf 100644
--- a/src/util/virrandom.c
+++ b/src/util/virrandom.c
@@ -27,7 +27,7 @@
#include <strings.h>
#include "virrandom.h"
-#include "threads.h"
+#include "virthread.h"
#include "count-one-bits.h"
#include "util.h"
#include "virterror_internal.h"
diff --git a/src/util/virterror.c b/src/util/virterror.c
index ce2d837..6c773d3 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -31,7 +31,7 @@
#include "datatypes.h"
#include "virlog.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "util.h"
virThreadLocal virLastErr;
diff --git a/src/util/virthread.c b/src/util/virthread.c
new file mode 100644
index 0000000..a062fd6
--- /dev/null
+++ b/src/util/virthread.c
@@ -0,0 +1,34 @@
+/*
+ * threads.c: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009-2010 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 "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"
+#else
+# error "Either pthreads or Win32 threads are required"
+#endif
diff --git a/src/util/virthread.h b/src/util/virthread.h
new file mode 100644
index 0000000..90aa5ce
--- /dev/null
+++ b/src/util/virthread.h
@@ -0,0 +1,166 @@
+/*
+ * threads.h: 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/>.
+ *
+ */
+
+#ifndef __THREADS_H_
+# define __THREADS_H_
+
+# include "internal.h"
+
+typedef struct virMutex virMutex;
+typedef virMutex *virMutexPtr;
+
+typedef struct virCond virCond;
+typedef virCond *virCondPtr;
+
+typedef struct virThreadLocal virThreadLocal;
+typedef virThreadLocal *virThreadLocalPtr;
+
+typedef struct virThread virThread;
+typedef virThread *virThreadPtr;
+
+typedef struct virOnceControl virOnceControl;
+typedef virOnceControl *virOnceControlPtr;
+
+typedef void (*virOnceFunc)(void);
+
+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);
+
+/* These next two functions are for debugging only, since they are not
+ * guaranteed to give unique values for distinct threads on all
+ * architectures, nor are the two functions guaranteed to give the same
+ * value for the same thread. */
+int virThreadSelfID(void);
+int virThreadID(virThreadPtr thread);
+
+/* Static initialization of mutexes is not possible, so we instead
+ * provide for guaranteed one-time initialization via a callback
+ * function. Usage:
+ * static virOnceControl once = VIR_ONCE_CONTROL_INITIALIZER;
+ * static void initializer(void) { ... }
+ * void myfunc()
+ * {
+ * if (virOnce(&once, initializer) < 0)
+ * goto error;
+ * ...now guaranteed that initializer has completed exactly once
+ * }
+ */
+int virOnce(virOnceControlPtr once, virOnceFunc init)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+
+int virMutexInit(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
+int virMutexInitRecursive(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
+void virMutexDestroy(virMutexPtr m);
+
+void virMutexLock(virMutexPtr m);
+void virMutexUnlock(virMutexPtr m);
+
+
+
+int virCondInit(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
+int virCondDestroy(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
+
+/* virCondWait, virCondWaitUntil:
+ * These functions can return without the associated predicate
+ * changing value. Therefore in nearly all cases they
+ * should be enclosed in a while loop that checks the predicate.
+ */
+int virCondWait(virCondPtr c, virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
+int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms)
ATTRIBUTE_RETURN_CHECK;
+
+void virCondSignal(virCondPtr c);
+void virCondBroadcast(virCondPtr c);
+
+
+typedef void (*virThreadLocalCleanup)(void *);
+int virThreadLocalInit(virThreadLocalPtr l,
+ virThreadLocalCleanup c) ATTRIBUTE_RETURN_CHECK;
+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:
+ * classname: base classname
+ *
+ * This macro simplifies the setup of a one-time only
+ * global file initializer.
+ *
+ * Assuming a class called "virMyObject", and a method
+ * implemented like:
+ *
+ * int virMyObjectOnceInit(void) {
+ * ...do init tasks...
+ * }
+ *
+ * Then invoking the macro:
+ *
+ * VIR_ONCE_GLOBAL_INIT(virMyObject)
+ *
+ * Will create a method
+ *
+ * int virMyObjectInitialize(void);
+ *
+ * Which will ensure that 'virMyObjectOnceInit' is
+ * guaranteed to be invoked exactly once.
+ */
+# define VIR_ONCE_GLOBAL_INIT(classname) \
+ static virOnceControl classname ## OnceControl = VIR_ONCE_CONTROL_INITIALIZER; \
+ static virErrorPtr classname ## OnceError = NULL; \
+ \
+ static void classname ## Once(void) \
+ { \
+ if (classname ## OnceInit() < 0) \
+ classname ## OnceError = virSaveLastError(); \
+ } \
+ \
+ static int classname ## Initialize(void) \
+ { \
+ if (virOnce(&classname ## OnceControl, classname ## Once) < 0) \
+ return -1; \
+ \
+ if (classname ## OnceError) { \
+ virSetError(classname ## OnceError); \
+ return -1; \
+ } \
+ \
+ return 0; \
+ }
+
+#endif
diff --git a/src/util/virthreadpool.c b/src/util/virthreadpool.c
index c13b078..307cefb 100644
--- a/src/util/virthreadpool.c
+++ b/src/util/virthreadpool.c
@@ -27,7 +27,7 @@
#include "virthreadpool.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virterror_internal.h"
#define VIR_FROM_THIS VIR_FROM_NONE
diff --git a/src/util/virthreadpthread.c b/src/util/virthreadpthread.c
new file mode 100644
index 0000000..37d8902
--- /dev/null
+++ b/src/util/virthreadpthread.c
@@ -0,0 +1,263 @@
+/*
+ * threads-pthread.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 <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 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(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 on BSD
+ * systems when pthread_t is a 64-bit pointer. */
+int virThreadSelfID(void)
+{
+#if defined(HAVE_SYS_SYSCALL_H) && defined(SYS_gettid)
+ pid_t tid;
+ tid = syscall(SYS_gettid);
+ return (int)tid;
+#else
+ return (int)(intptr_t)(void *)pthread_self();
+#endif
+}
+
+/* For debugging use only; this result is not guaranteed unique on BSD
+ * systems when pthread_t is a 64-bit pointer, nor does it match the
+ * thread id of virThreadSelfID on Linux. */
+int virThreadID(virThreadPtr thread)
+{
+ return (int)(uintptr_t)thread->thread;
+}
+
+void virThreadJoin(virThreadPtr thread)
+{
+ pthread_join(thread->thread, NULL);
+}
+
+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
new file mode 100644
index 0000000..ddaedb7
--- /dev/null
+++ b/src/util/virthreadpthread.h
@@ -0,0 +1,49 @@
+/*
+ * threads.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 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
new file mode 100644
index 0000000..c9f16c1
--- /dev/null
+++ b/src/util/virthreadwin32.c
@@ -0,0 +1,392 @@
+/*
+ * threads-win32.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 <config.h>
+
+#include <process.h>
+
+#include "viralloc.h"
+
+struct virThreadLocalData {
+ DWORD key;
+ virThreadLocalCleanup cleanup;
+};
+typedef struct virThreadLocalData virThreadLocalData;
+typedef virThreadLocalData *virThreadLocalDataPtr;
+
+virMutex virThreadLocalLock;
+unsigned int 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)
+{
+ unsigned int 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) {
+ unsigned int 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 threads-pthread.c. */
+int virThreadSelfID(void)
+{
+ return (int)GetCurrentThreadId();
+}
+
+/* For debugging use only; see comments in threads-pthread.c. */
+int 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;
+ }
+}
+
+
+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
new file mode 100644
index 0000000..07a1bf5
--- /dev/null
+++ b/src/util/virthreadwin32.h
@@ -0,0 +1,53 @@
+/*
+ * threads-win32.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;
+ unsigned int 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 }
diff --git a/src/vmware/vmware_conf.h b/src/vmware/vmware_conf.h
index b7a35a3..22d5240 100644
--- a/src/vmware/vmware_conf.h
+++ b/src/vmware/vmware_conf.h
@@ -25,7 +25,7 @@
# include "internal.h"
# include "domain_conf.h"
-# include "threads.h"
+# include "virthread.h"
# define VIR_FROM_THIS VIR_FROM_VMWARE
# define PROGRAM_SENTINAL ((char *)0x1)
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index b308605..5c8fe37 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -77,7 +77,7 @@
#include "virbuffer.h"
#include "capabilities.h"
#include "viralloc.h"
-#include "threads.h"
+#include "virthread.h"
#include "virfile.h"
#include "virnodesuspend.h"
#include "virtypedparam.h"
diff --git a/tests/eventtest.c b/tests/eventtest.c
index cd36a2d..6d00ea8 100644
--- a/tests/eventtest.c
+++ b/tests/eventtest.c
@@ -28,7 +28,7 @@
#include "testutils.h"
#include "internal.h"
-#include "threads.h"
+#include "virthread.h"
#include "virlog.h"
#include "util.h"
#include "vireventpoll.h"
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 224ca93..8c29a46 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -11,7 +11,7 @@
#include "internal.h"
#include "testutils.h"
#include "xml.h"
-#include "threads.h"
+#include "virthread.h"
#include "nwfilter_params.h"
#include "nwfilter_conf.h"
#include "testutilsqemu.h"
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 264c140..e1b6c56 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -22,7 +22,7 @@
#include "testutils.h"
#include "testutilsqemu.h"
#include "qemumonitortestutils.h"
-#include "threads.h"
+#include "virthread.h"
#include "virterror_internal.h"
diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c
index 1e3f0da..cc38803 100644
--- a/tests/qemumonitortestutils.c
+++ b/tests/qemumonitortestutils.c
@@ -26,7 +26,7 @@
#include "qemumonitortestutils.h"
-#include "threads.h"
+#include "virthread.h"
#include "qemu/qemu_monitor.h"
#include "rpc/virnetsocket.h"
#include "viralloc.h"
diff --git a/tests/testutils.c b/tests/testutils.c
index 7bb88f0..c6b1d23 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -41,7 +41,7 @@
#include "internal.h"
#include "viralloc.h"
#include "util.h"
-#include "threads.h"
+#include "virthread.h"
#include "virterror_internal.h"
#include "virbuffer.h"
#include "virlog.h"
diff --git a/tests/viratomictest.c b/tests/viratomictest.c
index 88f387b..1ed1707 100644
--- a/tests/viratomictest.c
+++ b/tests/viratomictest.c
@@ -26,7 +26,7 @@
#include "viratomic.h"
#include "virrandom.h"
-#include "threads.h"
+#include "virthread.h"
static int
testTypes(const void *data ATTRIBUTE_UNUSED)
diff --git a/tools/console.c b/tools/console.c
index 1d21189..d031308 100644
--- a/tools/console.c
+++ b/tools/console.c
@@ -42,7 +42,7 @@
# include "util.h"
# include "virfile.h"
# include "viralloc.h"
-# include "threads.h"
+# include "virthread.h"
# include "virterror_internal.h"
/*
diff --git a/tools/virsh.c b/tools/virsh.c
index e894aff..91a9677 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -64,7 +64,7 @@
#include "libvirt/libvirt-qemu.h"
#include "virfile.h"
#include "configmake.h"
-#include "threads.h"
+#include "virthread.h"
#include "vircommand.h"
#include "virkeycode.h"
#include "virnetdevbandwidth.h"
diff --git a/tools/virsh.h b/tools/virsh.h
index 6913ed1..6e6d3ee 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -35,7 +35,7 @@
# include "internal.h"
# include "virterror_internal.h"
-# include "threads.h"
+# include "virthread.h"
# include "virnetdevbandwidth.h"
# define VSH_MAX_XML_FILE (10*1024*1024)
--
1.7.11.7