[libvirt] [PATCH 23/28] Rename threads.{c,h} to virthread.{c,h}

Daniel P. Berrange berrange at redhat.com
Mon Dec 17 14:57:56 UTC 2012


From: "Daniel P. Berrange" <berrange at 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




More information about the libvir-list mailing list