]> xenbits.xensource.com Git - libvirt.git/commitdiff
Generic internal threads API
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 15 Jan 2009 19:56:05 +0000 (19:56 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 15 Jan 2009 19:56:05 +0000 (19:56 +0000)
42 files changed:
ChangeLog
po/POTFILES.in
proxy/Makefile.am
qemud/qemud.c
qemud/qemud.h
qemud/remote.c
src/Makefile.am
src/datatypes.c
src/datatypes.h
src/domain_conf.c
src/domain_conf.h
src/internal.h
src/libvirt.c
src/libvirt_private.syms
src/logging.c
src/lxc_conf.h
src/lxc_driver.c
src/network_conf.c
src/network_conf.h
src/network_driver.c
src/node_device.c
src/node_device_conf.c
src/node_device_conf.h
src/node_device_devkit.c
src/node_device_hal.c
src/openvz_conf.c
src/openvz_conf.h
src/openvz_driver.c
src/qemu_conf.h
src/qemu_driver.c
src/storage_conf.c
src/storage_conf.h
src/storage_driver.c
src/test.c
src/threads-pthread.c [new file with mode: 0644]
src/threads-pthread.h [new file with mode: 0644]
src/threads-win32.c [new file with mode: 0644]
src/threads-win32.h [new file with mode: 0644]
src/threads.c [new file with mode: 0644]
src/threads.h [new file with mode: 0644]
src/uml_conf.h
src/uml_driver.c

index 80f4be03597777eda3c77bfaa581ba40304319b2..4b10e2d745670537e045eb136a5b89e121ba9220 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Thu Jan 15 19:54:19 GMT 2009  Daniel P. Berrange <berrange@redhat.com>
+
+       Provide a generic internal API for threads support
+       * src/Makefile.am, src/threads.c, src/threads.h: Generic internal API for threads
+       * src/threads-pthread.c, src/threads-pthread.h: UNIX pthreads impl
+       * src/threads-win32.c, src/threads-win32.h: Win32 threads impl
+       * src/internal.h: Remove unnneccessary pthreads macros
+       * src/libvirt_private.syms: Add symbols for internal threads API
+       * po/POTFILES.in: Add node_device_conf.c
+       * proxy/Makefile.am: Add threads.c to build
+       * qemud/qemud.c, qemud/qemud.h, qemud/remote.c, src/datatypes.c,
+       src/datatypes.h, src/domain_conf.c, src/domain_conf.h,
+       src/libvirt.c, src/logging.c, src/lxc_conf.h, src/lxc_driver.c,
+       src/network_conf.c, src/network_conf.h, src/network_driver.c,
+       src/node_device.c, src/node_device_conf.c, src/node_device_conf.h,
+       src/node_device_devkit.c, src/node_device_hal.c, src/openvz_conf.c,
+       src/openvz_conf.h, src/openvz_driver.c, src/qemu_conf.h,
+       src/qemu_driver.c, src/storage_conf.c, src/storage_conf.h,
+       src/storage_driver.c, src/test.c, src/uml_conf.h, src/uml_driver.c:
+       Switch over to internal threads API instead of pthreads
+
+
+
+
 Thu Jan 15 19:39:19 GMT 2009  Daniel P. Berrange <berrange@redhat.com>
 
        * src/util.c: Implement virKill() for Win32 platform
index 26617a06a9bba30fffc3490405ab7865edc322c7..4a434ff2f52032ece35e2916b14476daa74ad19d 100644 (file)
@@ -14,6 +14,7 @@ src/lxc_driver.c
 src/network_conf.c
 src/network_driver.c
 src/node_device.c
+src/node_device_conf.c
 src/openvz_conf.c
 src/openvz_driver.c
 src/proxy_internal.c
index b680a1b306eb7d9578ba1f6c7bd1bfc084dcd286..d4a2fc495ab9d14cd9936e4c770daf071422a8b9 100644 (file)
@@ -12,6 +12,7 @@ libexec_PROGRAMS = libvirt_proxy
 libvirt_proxy_SOURCES = libvirt_proxy.c @top_srcdir@/src/xend_internal.c \
            @top_srcdir@/src/xen_internal.c @top_srcdir@/src/virterror.c \
            @top_srcdir@/src/sexpr.c  \
+           @top_srcdir@/src/threads.c  \
             @top_srcdir@/src/xs_internal.c @top_srcdir@/src/buf.c \
             @top_srcdir@/src/capabilities.c \
             @top_srcdir@/src/memory.c \
index 6a2db78c89ec26f08af5fdf24f24e508eebe6e87..5eec6c0590019b9b4158f0e2e3c833f7f20d7d85 100644 (file)
@@ -268,11 +268,11 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
     siginfo_t siginfo;
     int ret;
 
-    pthread_mutex_lock(&server->lock);
+    virMutexLock(&server->lock);
 
     if (saferead(server->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
         VIR_ERROR(_("Failed to read from signal pipe: %s"), strerror(errno));
-        pthread_mutex_unlock(&server->lock);
+        virMutexUnlock(&server->lock);
         return;
     }
 
@@ -300,7 +300,7 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
     if (ret != 0)
         server->shutdown = 1;
 
-    pthread_mutex_unlock(&server->lock);
+    virMutexUnlock(&server->lock);
 }
 
 int qemudSetCloseExec(int fd) {
@@ -688,9 +688,14 @@ static struct qemud_server *qemudInitialize(int sigread) {
         return NULL;
     }
 
-    if (pthread_mutex_init(&server->lock, NULL) != 0) {
+    if (virMutexInit(&server->lock) < 0) {
+        VIR_ERROR("%s", _("cannot initialize mutex"));
+        VIR_FREE(server);
+    }
+    if (virCondInit(&server->job) < 0) {
+        VIR_ERROR("%s", _("cannot initialize condition variable"));
+        virMutexDestroy(&server->lock);
         VIR_FREE(server);
-        return NULL;
     }
 
     server->sigread = sigread;
@@ -1117,8 +1122,11 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
 
     if (VIR_ALLOC(client) < 0)
         goto cleanup;
-    if (pthread_mutex_init(&client->lock, NULL) != 0)
+    if (virMutexInit(&client->lock) < 0) {
+        VIR_ERROR("%s", _("cannot initialize mutex"));
+        VIR_FREE(client);
         goto cleanup;
+    }
 
     client->magic = QEMUD_CLIENT_MAGIC;
     client->fd = fd;
@@ -1233,12 +1241,12 @@ static struct qemud_client *qemudPendingJob(struct qemud_server *server)
 {
     int i;
     for (i = 0 ; i < server->nclients ; i++) {
-        pthread_mutex_lock(&server->clients[i]->lock);
+        virMutexLock(&server->clients[i]->lock);
         if (server->clients[i]->mode == QEMUD_MODE_WAIT_DISPATCH) {
             /* Delibrately don't unlock client - caller wants the lock */
             return server->clients[i];
         }
-        pthread_mutex_unlock(&server->clients[i]->lock);
+        virMutexUnlock(&server->clients[i]->lock);
     }
     return NULL;
 }
@@ -1250,10 +1258,14 @@ static void *qemudWorker(void *data)
     while (1) {
         struct qemud_client *client;
         int len;
-        pthread_mutex_lock(&server->lock);
-        while ((client = qemudPendingJob(server)) == NULL)
-            pthread_cond_wait(&server->job, &server->lock);
-        pthread_mutex_unlock(&server->lock);
+        virMutexLock(&server->lock);
+        while ((client = qemudPendingJob(server)) == NULL) {
+            if (virCondWait(&server->job, &server->lock) < 0) {
+                virMutexUnlock(&server->lock);
+                return NULL;
+            }
+        }
+        virMutexUnlock(&server->lock);
 
         /* We own a locked client now... */
         client->mode = QEMUD_MODE_IN_DISPATCH;
@@ -1271,8 +1283,8 @@ static void *qemudWorker(void *data)
             qemudDispatchClientFailure(server, client);
 
         client->refs--;
-        pthread_mutex_unlock(&client->lock);
-        pthread_mutex_unlock(&server->lock);
+        virMutexUnlock(&client->lock);
+        virMutexUnlock(&server->lock);
     }
 }
 
@@ -1444,7 +1456,7 @@ static void qemudDispatchClientRead(struct qemud_server *server, struct qemud_cl
         if (qemudRegisterClientEvent(server, client, 1) < 0)
             qemudDispatchClientFailure(server, client);
 
-        pthread_cond_signal(&server->job);
+        virCondSignal(&server->job);
 
         break;
     }
@@ -1627,7 +1639,7 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
     struct qemud_client *client = NULL;
     int i;
 
-    pthread_mutex_lock(&server->lock);
+    virMutexLock(&server->lock);
 
     for (i = 0 ; i < server->nclients ; i++) {
         if (server->clients[i]->watch == watch) {
@@ -1637,12 +1649,12 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
     }
 
     if (!client) {
-        pthread_mutex_unlock(&server->lock);
+        virMutexUnlock(&server->lock);
         return;
     }
 
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     if (client->fd != fd)
         return;
@@ -1653,7 +1665,7 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
         qemudDispatchClientRead(server, client);
     else
         qemudDispatchClientFailure(server, client);
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
 }
 
 static int qemudRegisterClientEvent(struct qemud_server *server,
@@ -1703,7 +1715,7 @@ qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
     struct qemud_server *server = (struct qemud_server *)opaque;
     struct qemud_socket *sock;
 
-    pthread_mutex_lock(&server->lock);
+    virMutexLock(&server->lock);
 
     sock = server->sockets;
 
@@ -1717,7 +1729,7 @@ qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
     if (sock && sock->fd == fd && events)
         qemudDispatchServer(server, sock);
 
-    pthread_mutex_unlock(&server->lock);
+    virMutexUnlock(&server->lock);
 }
 
 
@@ -1752,7 +1764,7 @@ static int qemudRunLoop(struct qemud_server *server) {
     int timerid = -1;
     int ret = -1, i;
 
-    pthread_mutex_lock(&server->lock);
+    virMutexLock(&server->lock);
 
     server->nworkers = min_workers;
     if (VIR_ALLOC_N(server->workers, server->nworkers) < 0) {
@@ -1783,21 +1795,22 @@ static int qemudRunLoop(struct qemud_server *server) {
             DEBUG("Scheduling shutdown timer %d", timerid);
         }
 
-        pthread_mutex_unlock(&server->lock);
+        virMutexUnlock(&server->lock);
         if (qemudOneLoop() < 0)
             break;
-        pthread_mutex_lock(&server->lock);
+        virMutexLock(&server->lock);
 
     reprocess:
         for (i = 0 ; i < server->nclients ; i++) {
             int inactive;
-            pthread_mutex_lock(&server->clients[i]->lock);
+            virMutexLock(&server->clients[i]->lock);
             inactive = server->clients[i]->fd == -1
                 && server->clients[i]->refs == 0;
-            pthread_mutex_unlock(&server->clients[i]->lock);
+            virMutexUnlock(&server->clients[i]->lock);
             if (inactive) {
                 if (server->clients[i]->conn)
                     virConnectClose(server->clients[i]->conn);
+                virMutexDestroy(&server->clients[i]->lock);
                 VIR_FREE(server->clients[i]);
                 server->nclients--;
                 if (i < server->nclients) {
@@ -1826,13 +1839,13 @@ static int qemudRunLoop(struct qemud_server *server) {
 
     for (i = 0 ; i < server->nworkers ; i++) {
         pthread_t thread = server->workers[i];
-        pthread_mutex_unlock(&server->lock);
+        virMutexUnlock(&server->lock);
         pthread_join(thread, NULL);
-        pthread_mutex_lock(&server->lock);
+        virMutexLock(&server->lock);
     }
 
     free(server->workers);
-    pthread_mutex_unlock(&server->lock);
+    virMutexUnlock(&server->lock);
     return ret;
 }
 
@@ -1862,7 +1875,12 @@ static void qemudCleanup(struct qemud_server *server) {
 
     virStateCleanup();
 
-    free(server);
+    if (virCondDestroy(&server->job) < 0) {
+        ;
+    }
+    virMutexDestroy(&server->lock);
+
+    VIR_FREE(server);
 }
 
 /* Allocate an array of malloc'd strings from the config file, filename
index 42066cbf9837aa86bdbc4beb5151a623f5cb590a..12897a12bfc2a616ffa01cc731b4c0857d61988f 100644 (file)
@@ -46,6 +46,7 @@
 #include <rpc/xdr.h>
 #include "remote_protocol.h"
 #include "logging.h"
+#include "threads.h"
 
 #ifdef __GNUC__
 #ifdef HAVE_ANSIDECL_H
@@ -88,7 +89,7 @@ enum qemud_sock_type {
 
 /* Stores the per-client connection state */
 struct qemud_client {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     int magic;
 
@@ -149,8 +150,8 @@ struct qemud_socket {
 
 /* Main server state */
 struct qemud_server {
-    pthread_mutex_t lock;
-    pthread_cond_t job;
+    virMutex lock;
+    virCond job;
 
     int nworkers;
     pthread_t *workers;
index a5a84cceb1fa59bedd1d7274718bb0cf59bfafb1..25a6f4bd167ae21d3004241d12700801124ea8c2 100644 (file)
@@ -301,7 +301,7 @@ remoteDispatchClientRequest (struct qemud_server *server,
 
     /* Call function. */
     conn = client->conn;
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
 
     /*
      * When the RPC handler is called:
@@ -315,9 +315,9 @@ remoteDispatchClientRequest (struct qemud_server *server,
      */
     rv = (data->fn)(server, client, conn, &rerr, &args, &ret);
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     xdr_free (data->args_filter, (char*)&args);
 
@@ -412,9 +412,9 @@ remoteDispatchOpen (struct qemud_server *server,
         return -1;
     }
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     name = args->name ? *args->name : NULL;
 
@@ -433,7 +433,7 @@ remoteDispatchOpen (struct qemud_server *server,
         remoteDispatchConnError(rerr, NULL);
 
     rc = client->conn ? 0 : -1;
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return rc;
 }
 
@@ -450,13 +450,13 @@ remoteDispatchClose (struct qemud_server *server ATTRIBUTE_UNUSED,
                      remote_error *rerr ATTRIBUTE_UNUSED,
                      void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED)
 {
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     client->closing = 1;
 
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return 0;
 }
 
@@ -2472,11 +2472,11 @@ remoteDispatchAuthList (struct qemud_server *server,
         remoteDispatchOOMError(rerr);
         return -1;
     }
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
     ret->types.types_val[0] = client->auth;
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
 
     return 0;
 }
@@ -2535,9 +2535,9 @@ remoteDispatchAuthSaslInit (struct qemud_server *server,
     socklen_t salen;
     char *localAddr, *remoteAddr;
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     REMOTE_DEBUG("Initialize SASL auth %d", client->fd);
     if (client->auth != REMOTE_AUTH_SASL ||
@@ -2663,13 +2663,13 @@ remoteDispatchAuthSaslInit (struct qemud_server *server,
         goto authfail;
     }
 
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return 0;
 
 authfail:
     remoteDispatchAuthError(rerr);
 error:
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return -1;
 }
 
@@ -2787,9 +2787,9 @@ remoteDispatchAuthSaslStart (struct qemud_server *server,
     unsigned int serveroutlen;
     int err;
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     REMOTE_DEBUG("Start SASL auth %d", client->fd);
     if (client->auth != REMOTE_AUTH_SASL ||
@@ -2851,13 +2851,13 @@ remoteDispatchAuthSaslStart (struct qemud_server *server,
         client->auth = REMOTE_AUTH_NONE;
     }
 
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return 0;
 
 authfail:
     remoteDispatchAuthError(rerr);
 error:
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return -1;
 }
 
@@ -2874,9 +2874,9 @@ remoteDispatchAuthSaslStep (struct qemud_server *server,
     unsigned int serveroutlen;
     int err;
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     REMOTE_DEBUG("Step SASL auth %d", client->fd);
     if (client->auth != REMOTE_AUTH_SASL ||
@@ -2939,13 +2939,13 @@ remoteDispatchAuthSaslStep (struct qemud_server *server,
         client->auth = REMOTE_AUTH_NONE;
     }
 
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return 0;
 
 authfail:
     remoteDispatchAuthError(rerr);
 error:
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return -1;
 }
 
@@ -3011,9 +3011,9 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
     DBusError err;
     const char *action;
 
-    pthread_mutex_lock(&server->lock);
-    pthread_mutex_lock(&client->lock);
-    pthread_mutex_unlock(&server->lock);
+    virMutexLock(&server->lock);
+    virMutexLock(&client->lock);
+    virMutexUnlock(&server->lock);
 
     action = client->readonly ?
         "org.libvirt.unix.monitor" :
@@ -3091,12 +3091,12 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
     ret->complete = 1;
     client->auth = REMOTE_AUTH_NONE;
 
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return 0;
 
 authfail:
     remoteDispatchAuthError(rerr);
-    pthread_mutex_unlock(&client->lock);
+    virMutexUnlock(&client->lock);
     return -1;
 }
 
index dd7dea8f34b7465465266a652ce5c7f9d410e14a..8989a8fb0a5caf492592c3ee18a169a8facccbba 100644 (file)
@@ -46,14 +46,19 @@ UTIL_SOURCES =                                                      \
                event.c event.h                                 \
                hash.c hash.h                                   \
                iptables.c iptables.h                           \
+               logging.c logging.h                             \
                memory.c memory.h                               \
                qparams.c qparams.h                             \
+               threads.c threads.h                             \
+               threads-pthread.h                               \
+               threads-win32.h                                 \
                uuid.c uuid.h                                   \
                util.c util.h                                   \
                virterror.c virterror_internal.h                \
-               logging.c logging.h                             \
                xml.c xml.h
 
+EXTRA_DIST += threads-pthread.c threads-win32.c
+
 # Internal generic driver infrastructure
 DRIVER_SOURCES =                                               \
                driver.c driver.h                               \
index 82acd080dfa775d1eda199d8d3c6c7ac30e09189..f602ef230ecb21b11458be314b9d2713e1a461a2 100644 (file)
@@ -123,6 +123,11 @@ virGetConnect(void) {
         virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
         goto failed;
     }
+    if (virMutexInit(&ret->lock) < 0) {
+        VIR_FREE(ret);
+        goto failed;
+    }
+
     ret->magic = VIR_CONNECT_MAGIC;
     ret->driver = NULL;
     ret->networkDriver = NULL;
@@ -144,8 +149,6 @@ virGetConnect(void) {
     if (ret->nodeDevices == NULL)
         goto failed;
 
-    pthread_mutex_init(&ret->lock, NULL);
-
     ret->refs = 1;
     return(ret);
 
@@ -162,7 +165,7 @@ failed:
         if (ret->nodeDevices != NULL)
             virHashFree(ret->nodeDevices, (virHashDeallocator) virNodeDeviceFree);
 
-        pthread_mutex_destroy(&ret->lock);
+        virMutexDestroy(&ret->lock);
         VIR_FREE(ret);
     }
     return(NULL);
@@ -197,8 +200,8 @@ virReleaseConnect(virConnectPtr conn) {
 
     xmlFreeURI(conn->uri);
 
-    pthread_mutex_unlock(&conn->lock);
-    pthread_mutex_destroy(&conn->lock);
+    virMutexUnlock(&conn->lock);
+    virMutexDestroy(&conn->lock);
     VIR_FREE(conn);
 }
 
@@ -219,7 +222,7 @@ virUnrefConnect(virConnectPtr conn) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
     DEBUG("unref connection %p %d", conn, conn->refs);
     conn->refs--;
     refs = conn->refs;
@@ -228,7 +231,7 @@ virUnrefConnect(virConnectPtr conn) {
         /* Already unlocked mutex */
         return (0);
     }
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return (refs);
 }
 
@@ -253,7 +256,7 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
 
     /* TODO search by UUID first as they are better differenciators */
 
@@ -286,11 +289,11 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
         DEBUG("Existing hash entry %p: refs now %d", ret, ret->refs+1);
     }
     ret->refs++;
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return(ret);
 
  error:
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     if (ret != NULL) {
         VIR_FREE(ret->name);
         VIR_FREE(ret);
@@ -337,7 +340,7 @@ virReleaseDomain(virDomainPtr domain) {
         return;
     }
 
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
 }
 
 
@@ -358,7 +361,7 @@ virUnrefDomain(virDomainPtr domain) {
         virLibConnError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    pthread_mutex_lock(&domain->conn->lock);
+    virMutexLock(&domain->conn->lock);
     DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs);
     domain->refs--;
     refs = domain->refs;
@@ -368,7 +371,7 @@ virUnrefDomain(virDomainPtr domain) {
         return (0);
     }
 
-    pthread_mutex_unlock(&domain->conn->lock);
+    virMutexUnlock(&domain->conn->lock);
     return (refs);
 }
 
@@ -393,7 +396,7 @@ virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
 
     /* TODO search by UUID first as they are better differenciators */
 
@@ -422,11 +425,11 @@ virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
         conn->refs++;
     }
     ret->refs++;
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return(ret);
 
  error:
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     if (ret != NULL) {
         VIR_FREE(ret->name);
         VIR_FREE(ret);
@@ -473,7 +476,7 @@ virReleaseNetwork(virNetworkPtr network) {
         return;
     }
 
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
 }
 
 
@@ -494,7 +497,7 @@ virUnrefNetwork(virNetworkPtr network) {
         virLibConnError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    pthread_mutex_lock(&network->conn->lock);
+    virMutexLock(&network->conn->lock);
     DEBUG("unref network %p %s %d", network, network->name, network->refs);
     network->refs--;
     refs = network->refs;
@@ -504,7 +507,7 @@ virUnrefNetwork(virNetworkPtr network) {
         return (0);
     }
 
-    pthread_mutex_unlock(&network->conn->lock);
+    virMutexUnlock(&network->conn->lock);
     return (refs);
 }
 
@@ -530,7 +533,7 @@ virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uui
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
 
     /* TODO search by UUID first as they are better differenciators */
 
@@ -559,11 +562,11 @@ virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uui
         conn->refs++;
     }
     ret->refs++;
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return(ret);
 
 error:
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     if (ret != NULL) {
         VIR_FREE(ret->name);
         VIR_FREE(ret);
@@ -606,7 +609,7 @@ virReleaseStoragePool(virStoragePoolPtr pool) {
         return;
     }
 
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
 }
 
 
@@ -627,7 +630,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
         virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    pthread_mutex_lock(&pool->conn->lock);
+    virMutexLock(&pool->conn->lock);
     DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs);
     pool->refs--;
     refs = pool->refs;
@@ -637,7 +640,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
         return (0);
     }
 
-    pthread_mutex_unlock(&pool->conn->lock);
+    virMutexUnlock(&pool->conn->lock);
     return (refs);
 }
 
@@ -664,7 +667,7 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
 
     ret = (virStorageVolPtr) virHashLookup(conn->storageVols, key);
     if (ret == NULL) {
@@ -695,11 +698,11 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
         conn->refs++;
     }
     ret->refs++;
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return(ret);
 
 error:
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     if (ret != NULL) {
         VIR_FREE(ret->name);
         VIR_FREE(ret->pool);
@@ -744,7 +747,7 @@ virReleaseStorageVol(virStorageVolPtr vol) {
         return;
     }
 
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
 }
 
 
@@ -765,7 +768,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
         virLibConnError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    pthread_mutex_lock(&vol->conn->lock);
+    virMutexLock(&vol->conn->lock);
     DEBUG("unref vol %p %s %d", vol, vol->name, vol->refs);
     vol->refs--;
     refs = vol->refs;
@@ -775,7 +778,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
         return (0);
     }
 
-    pthread_mutex_unlock(&vol->conn->lock);
+    virMutexUnlock(&vol->conn->lock);
     return (refs);
 }
 
@@ -801,7 +804,7 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    pthread_mutex_lock(&conn->lock);
+    virMutexLock(&conn->lock);
 
     ret = (virNodeDevicePtr) virHashLookup(conn->nodeDevices, name);
     if (ret == NULL) {
@@ -825,11 +828,11 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
         conn->refs++;
     }
     ret->refs++;
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     return(ret);
 
 error:
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
     if (ret != NULL) {
         VIR_FREE(ret->name);
         VIR_FREE(ret);
@@ -872,7 +875,7 @@ virReleaseNodeDevice(virNodeDevicePtr dev) {
         return;
     }
 
-    pthread_mutex_unlock(&conn->lock);
+    virMutexUnlock(&conn->lock);
 }
 
 
@@ -889,7 +892,7 @@ int
 virUnrefNodeDevice(virNodeDevicePtr dev) {
     int refs;
 
-    pthread_mutex_lock(&dev->conn->lock);
+    virMutexLock(&dev->conn->lock);
     DEBUG("unref dev %p %s %d", dev, dev->name, dev->refs);
     dev->refs--;
     refs = dev->refs;
@@ -899,6 +902,6 @@ virUnrefNodeDevice(virNodeDevicePtr dev) {
         return (0);
     }
 
-    pthread_mutex_unlock(&dev->conn->lock);
+    virMutexUnlock(&dev->conn->lock);
     return (refs);
 }
index 6512537896c4ec8fca5a053fa1336901e9c1c0df..d1bc88f7610a698989ed16ac7936945c59635dd5 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "hash.h"
 #include "driver.h"
-
+#include "threads.h"
 
 /**
  * VIR_CONNECT_MAGIC:
@@ -125,7 +125,7 @@ struct _virConnect {
      * count of any virDomain/virNetwork object associated with
      * this connection
      */
-    PTHREAD_MUTEX_T (lock);
+    virMutex lock;
     virHashTablePtr domains;  /* hash table for known domains */
     virHashTablePtr networks; /* hash table for known domains */
     virHashTablePtr storagePools;/* hash table for known storage pools */
index 8bb51f7f06db2afcef75abf0c15fc5f45ff5e5f1..4250d81c764f2dd6ebea61e96f66da7560f4383f 100644 (file)
@@ -433,6 +433,8 @@ void virDomainObjFree(virDomainObjPtr dom)
     VIR_FREE(dom->monitorpath);
     VIR_FREE(dom->vcpupids);
 
+    virMutexDestroy(&dom->lock);
+
     VIR_FREE(dom);
 }
 
@@ -471,7 +473,13 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
         return NULL;
     }
 
-    pthread_mutex_init(&domain->lock, NULL);
+    if (virMutexInit(&domain->lock) < 0) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             "%s", _("cannot initialize mutex"));
+        VIR_FREE(domain);
+        return NULL;
+    }
+
     virDomainObjLock(domain);
     domain->state = VIR_DOMAIN_SHUTOFF;
     domain->def = def;
@@ -3660,26 +3668,14 @@ const char *virDomainDefDefaultEmulator(virConnectPtr conn,
 }
 
 
-#ifdef HAVE_PTHREAD_H
-
 void virDomainObjLock(virDomainObjPtr obj)
 {
-    pthread_mutex_lock(&obj->lock);
+    virMutexLock(&obj->lock);
 }
 
 void virDomainObjUnlock(virDomainObjPtr obj)
 {
-    pthread_mutex_unlock(&obj->lock);
+    virMutexUnlock(&obj->lock);
 }
 
-#else
-void virDomainObjLock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-
-void virDomainObjUnlock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-#endif
-
 #endif /* ! PROXY */
index 7320609faee29edd0633cfd9253454327b013ab8..1e5c10369aa86aad33f556ef5f93b27dd9fb4df6 100644 (file)
@@ -31,6 +31,7 @@
 #include "internal.h"
 #include "capabilities.h"
 #include "util.h"
+#include "threads.h"
 
 /* Different types of hypervisor */
 /* NB: Keep in sync with virDomainVirtTypeToString impl */
@@ -456,7 +457,7 @@ struct _virDomainDef {
 typedef struct _virDomainObj virDomainObj;
 typedef virDomainObj *virDomainObjPtr;
 struct _virDomainObj {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     int stdin_fd;
     int stdout_fd;
index 696e5db1a38645d2fedcd65b128685c9c7956556..adb65076ea301969960b016f503be87cb341232c 100644 (file)
 #include <sys/syslimits.h>
 #endif
 
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#define PTHREAD_MUTEX_T(v) pthread_mutex_t v
-#else
-/* Mutex functions disappear if we don't have pthread. */
-#define PTHREAD_MUTEX_T(v) /*empty*/
-#define pthread_mutex_init(lk,p) /*empty*/
-#define pthread_mutex_destroy(lk) /*empty*/
-#define pthread_mutex_lock(lk) /*empty*/
-#define pthread_mutex_unlock(lk) /*empty*/
-#define pthread_sigmask(h, s, o) sigprocmask((h), (s), (o))
-#endif
-
 /* The library itself is allowed to use deprecated functions /
  * variables, so effectively undefine the deprecated attribute
  * which would otherwise be defined in libvirt.h.
index a96eecd40bee162fdc5a4d193cc39dbf52da95ca..900bc62d876598d942dabf22273d4347d6779a95 100644 (file)
@@ -253,8 +253,12 @@ virInitialize(void)
 #endif
     if (initialized)
         return(0);
+
     initialized = 1;
 
+    if (virThreadInitialize() < 0)
+        return -1;
+
 #ifdef ENABLE_DEBUG
     debugEnv = getenv("LIBVIRT_DEBUG");
     if (debugEnv && *debugEnv && *debugEnv != '0') {
@@ -316,6 +320,43 @@ virInitialize(void)
     return(0);
 }
 
+#ifdef WIN32
+BOOL WINAPI
+DllMain (HINSTANCE instance, DWORD reason, LPVOID ignore);
+
+BOOL WINAPI
+DllMain (HINSTANCE instance ATTRIBUTE_UNUSED,
+         DWORD reason,
+         LPVOID ignore ATTRIBUTE_UNUSED)
+{
+    switch (reason) {
+    case DLL_PROCESS_ATTACH:
+        fprintf(stderr, "Initializing DLL\n");
+        virInitialize();
+        break;
+
+    case DLL_THREAD_ATTACH:
+        fprintf(stderr, "Thread start\n");
+        /* Nothing todo in libvirt yet */
+        break;
+
+    case DLL_THREAD_DETACH:
+        fprintf(stderr, "Thread exit\n");
+        /* Release per-thread local data */
+        virThreadOnExit();
+        break;
+
+    case DLL_PROCESS_DETACH:
+        fprintf(stderr, "Process exit\n");
+        /* Don't bother releasing per-thread data
+           since (hopefully) windows cleans up
+           everything on process exit */
+        break;
+    }
+
+    return TRUE;
+}
+#endif
 
 
 /**
index 6b48ea4f391791fbf8902d3459f86690cdc8d85c..c76b6c2376afe8c62d69e0f16040959623b8daee 100644 (file)
@@ -261,6 +261,18 @@ virStoragePoolObjLock;
 virStoragePoolObjUnlock;
 
 
+# threads.h
+virMutexInit;
+virMutexDestroy;
+virMutexLock;
+virMutexUnlock;
+
+virCondInit;
+virCondDestroy;
+virCondWait;
+virCondSignal;
+virCondBroadcast;
+
 # util.h
 virFileReadAll;
 virStrToLong_i;
index 8fb64286caec5ac82fa3d1891d5627fbfa764ae4..d6bd22aa8b915e8367e65432f87a8b98a80671e1 100644 (file)
@@ -37,6 +37,7 @@
 #include "logging.h"
 #include "memory.h"
 #include "util.h"
+#include "threads.h"
 
 #ifdef ENABLE_DEBUG
 int debugFlag = 0;
@@ -129,15 +130,15 @@ static int virLogResetOutputs(void);
 /*
  * Logs accesses must be serialized though a mutex
  */
-PTHREAD_MUTEX_T(virLogMutex);
+virMutex virLogMutex;
 
 static void virLogLock(void)
 {
-    pthread_mutex_lock(&virLogMutex);
+    virMutexLock(&virLogMutex);
 }
 static void virLogUnlock(void)
 {
-    pthread_mutex_unlock(&virLogMutex);
+    virMutexUnlock(&virLogMutex);
 }
 
 
@@ -167,8 +168,11 @@ static int virLogInitialized = 0;
 int virLogStartup(void) {
     if (virLogInitialized)
         return(-1);
+
+    if (virMutexInit(&virLogMutex) < 0)
+        return -1;
+
     virLogInitialized = 1;
-    pthread_mutex_init(&virLogMutex, NULL);
     virLogLock();
     virLogLen = 0;
     virLogStart = 0;
@@ -214,7 +218,7 @@ void virLogShutdown(void) {
     virLogStart = 0;
     virLogEnd = 0;
     virLogUnlock();
-    pthread_mutex_destroy(&virLogMutex);
+    virMutexDestroy(&virLogMutex);
     virLogInitialized = 0;
 }
 
index 3b52f39a9aac1c4c99bc5c24ef178230067ce6c8..b3d2a8aaeff915aba1315022028a085b9104bb90 100644 (file)
@@ -29,6 +29,7 @@
 #include "internal.h"
 #include "domain_conf.h"
 #include "capabilities.h"
+#include "threads.h"
 
 #define LXC_CONFIG_DIR SYSCONF_DIR "/libvirt/lxc"
 #define LXC_STATE_DIR LOCAL_STATE_DIR "/run/libvirt/lxc"
@@ -36,7 +37,7 @@
 
 typedef struct __lxc_driver lxc_driver_t;
 struct __lxc_driver {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virCapsPtr caps;
 
index 13afae0bc4c760b4cc3efc8b9c26ab22c341f531..2e9625a6195d87244e3ae7290476be46aec5ca3d 100644 (file)
@@ -57,11 +57,11 @@ static lxc_driver_t *lxc_driver = NULL;
 
 static void lxcDriverLock(lxc_driver_t *driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 static void lxcDriverUnlock(lxc_driver_t *driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 
@@ -1135,7 +1135,10 @@ static int lxcStartup(void)
     if (VIR_ALLOC(lxc_driver) < 0) {
         return -1;
     }
-    pthread_mutex_init(&lxc_driver->lock, NULL);
+    if (virMutexInit(&lxc_driver->lock) < 0) {
+        VIR_FREE(lxc_driver);
+        return -1;
+    }
     lxcDriverLock(lxc_driver);
 
     /* Check that this is a container enabled kernel */
@@ -1228,6 +1231,7 @@ static int lxcShutdown(void)
     VIR_FREE(lxc_driver->stateDir);
     VIR_FREE(lxc_driver->logDir);
     lxcDriverUnlock(lxc_driver);
+    virMutexDestroy(&lxc_driver->lock);
     VIR_FREE(lxc_driver);
     lxc_driver = NULL;
 
index b0c16e612960fd926260ac05933d27aff1b185a7..410f255cee46810d05ad6b24191fd88b44b56277 100644 (file)
@@ -126,6 +126,8 @@ void virNetworkObjFree(virNetworkObjPtr net)
     VIR_FREE(net->configFile);
     VIR_FREE(net->autostartLink);
 
+    virMutexDestroy(&net->lock);
+
     VIR_FREE(net);
 }
 
@@ -163,7 +165,12 @@ virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
         virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
         return NULL;
     }
-    pthread_mutex_init(&network->lock, NULL);
+    if (virMutexInit(&network->lock) < 0) {
+        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                              "%s", _("cannot initialize mutex"));
+        VIR_FREE(network);
+        return NULL;
+    }
     virNetworkObjLock(network);
     network->def = def;
 
@@ -823,25 +830,13 @@ int virNetworkDeleteConfig(virConnectPtr conn,
     return 0;
 }
 
-#ifdef HAVE_PTHREAD_H
-
 void virNetworkObjLock(virNetworkObjPtr obj)
 {
-    pthread_mutex_lock(&obj->lock);
+    virMutexLock(&obj->lock);
 }
 
 void virNetworkObjUnlock(virNetworkObjPtr obj)
 {
-    pthread_mutex_unlock(&obj->lock);
-}
-
-#else
-void virNetworkObjLock(virNetworkObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-
-void virNetworkObjUnlock(virNetworkObjPtr obj ATTRIBUTE_UNUSED)
-{
+    virMutexUnlock(&obj->lock);
 }
 
-#endif
index 47bfc6e3070ce3124d22da366198794dc1fed95d..733ad51922172ea7bebe5ee9e5bf693ed9c0ff21 100644 (file)
@@ -29,6 +29,7 @@
 #include <libxml/xpath.h>
 
 #include "internal.h"
+#include "threads.h"
 
 /* 2 possible types of forwarding */
 enum virNetworkForwardType {
@@ -82,7 +83,7 @@ struct _virNetworkDef {
 typedef struct _virNetworkObj virNetworkObj;
 typedef virNetworkObj *virNetworkObjPtr;
 struct _virNetworkObj {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     pid_t dnsmasqPid;
     unsigned int active : 1;
index 04671aa83c626a42173dc859bf994b7e337016e1..85d83ebce69526597fd86f148707c0c4ad972829 100644 (file)
@@ -59,7 +59,7 @@
 
 /* Main driver state */
 struct network_driver {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virNetworkObjList networks;
 
@@ -73,11 +73,11 @@ struct network_driver {
 
 static void networkDriverLock(struct network_driver *driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 static void networkDriverUnlock(struct network_driver *driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 static int networkShutdown(void);
@@ -134,7 +134,10 @@ networkStartup(void) {
     if (VIR_ALLOC(driverState) < 0)
         goto error;
 
-    pthread_mutex_init(&driverState->lock, NULL);
+    if (virMutexInit(&driverState->lock) < 0) {
+        VIR_FREE(driverState);
+        goto error;
+    }
     networkDriverLock(driverState);
 
     if (!uid) {
@@ -290,6 +293,7 @@ networkShutdown(void) {
         iptablesContextFree(driverState->iptables);
 
     networkDriverUnlock(driverState);
+    virMutexDestroy(&driverState->lock);
 
     VIR_FREE(driverState);
 
index 753b9b99bb0255c1417742d0480bc4664ca306a5..9586fa63300f1fe3440ef8da63e63c5bc3751d6b 100644 (file)
@@ -48,12 +48,12 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
 void nodeDeviceLock(virDeviceMonitorStatePtr driver)
 {
     DEBUG("LOCK node %p", driver);
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 void nodeDeviceUnlock(virDeviceMonitorStatePtr driver)
 {
     DEBUG("UNLOCK node %p", driver);
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 static int nodeNumOfDevices(virConnectPtr conn,
index 9645c8917b9dbc5233c6f82973f711f28387b80f..ff022b7b91f63a8b8a51d066fa3dfae41fdb3222 100644 (file)
@@ -99,6 +99,8 @@ void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
     if (dev->privateFree)
         (*dev->privateFree)(dev->privateData);
 
+    virMutexDestroy(&dev->lock);
+
     VIR_FREE(dev);
 }
 
@@ -128,12 +130,18 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn,
         return NULL;
     }
 
-    pthread_mutex_init(&device->lock, NULL);
+    if (virMutexInit(&device->lock) < 0) {
+        virNodeDeviceReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                 "%s", _("cannot initialize mutex"));
+        VIR_FREE(device);
+        return NULL;
+    }
     virNodeDeviceObjLock(device);
     device->def = def;
 
     if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) {
         device->def = NULL;
+        virNodeDeviceObjUnlock(device);
         virNodeDeviceObjFree(device);
         virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL);
         return NULL;
@@ -408,26 +416,13 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
 }
 
 
-#ifdef HAVE_PTHREAD_H
-
 void virNodeDeviceObjLock(virNodeDeviceObjPtr obj)
 {
-    pthread_mutex_lock(&obj->lock);
+    virMutexLock(&obj->lock);
 }
 
 void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj)
 {
-    pthread_mutex_unlock(&obj->lock);
-}
-
-#else
-
-void virNodeDeviceObjLock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-
-void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED)
-{
+    virMutexUnlock(&obj->lock);
 }
 
-#endif
index 15a0757c04c5ec88f41ca61aea11fa371d8d44b3..202475595c06ef69bc38e05e7735385c847f19e7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "internal.h"
 #include "util.h"
+#include "threads.h"
 
 enum virNodeDevCapType {
     /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
@@ -142,7 +143,7 @@ struct _virNodeDeviceDef {
 typedef struct _virNodeDeviceObj virNodeDeviceObj;
 typedef virNodeDeviceObj *virNodeDeviceObjPtr;
 struct _virNodeDeviceObj {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virNodeDeviceDefPtr def;           /* device definition */
     void *privateData;                 /* driver-specific private data */
@@ -160,7 +161,7 @@ struct _virNodeDeviceObjList {
 typedef struct _virDeviceMonitorState virDeviceMonitorState;
 typedef virDeviceMonitorState *virDeviceMonitorStatePtr;
 struct _virDeviceMonitorState {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virNodeDeviceObjList devs;         /* currently-known devices */
     void *privateData;                 /* driver-specific private data */
index 199143c3f8a8f008d2830f347314db3f81e0f580..9e3fa6f1910a327e85ffdae47cefbd8fe9689768 100644 (file)
@@ -298,7 +298,10 @@ static int devkitDeviceMonitorStartup(void)
     if (VIR_ALLOC(driverState) < 0)
         return -1;
 
-    pthread_mutex_init(&driverState->lock, NULL);
+    if (virMutexInit(&driverState->lock) < 0) {
+        VIR_FREE(driverState);
+        return -1;
+    }
 
     g_type_init();
 
@@ -375,7 +378,8 @@ static int devkitDeviceMonitorShutdown(void)
         virNodeDeviceObjListFree(&driverState->devs);
         if (devkit_client)
             g_object_unref(devkit_client);
-        nodeDeviceLock(driverState);
+        nodeDeviceUnlock(driverState);
+        virMutexDestroy(&driveState->lock);
         VIR_FREE(driverState);
         return 0;
     }
index 3449ee0f7a9cc4e55efaa1a252f1cc20b9ae6f00..cb4f86b14ee471786c0c9b3b8515a42b22a5a0e0 100644 (file)
@@ -678,7 +678,10 @@ static int halDeviceMonitorStartup(void)
     if (VIR_ALLOC(driverState) < 0)
         return -1;
 
-    pthread_mutex_init(&driverState->lock, NULL);
+    if (virMutexInit(&driverState->lock) < 0) {
+        VIR_FREE(driverState);
+        return -1;
+    }
     nodeDeviceLock(driverState);
 
     /* Allocate and initialize a new HAL context */
@@ -770,6 +773,7 @@ static int halDeviceMonitorShutdown(void)
         (void)libhal_ctx_shutdown(hal_ctx, NULL);
         (void)libhal_ctx_free(hal_ctx);
         nodeDeviceUnlock(driverState);
+        virMutexDestroy(&driverState->lock);
         VIR_FREE(driverState);
         return 0;
     }
index 6fa02125f44492add7e1636814e1fd586521bdb4..54474b753d9e102bb8a75c6b71aa29573aa97bf4 100644 (file)
@@ -392,11 +392,18 @@ int openvzLoadDomains(struct openvz_driver *driver) {
             goto cleanup;
         }
 
-        if (VIR_ALLOC(dom) < 0 ||
-            VIR_ALLOC(dom->def) < 0)
+        if (VIR_ALLOC(dom) < 0)
             goto no_memory;
 
-        pthread_mutex_init(&dom->lock, NULL);
+        if (virMutexInit(&dom->lock) < 0) {
+            openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
+                        "%s", _("cannot initialize mutex"));
+            VIR_FREE(dom);
+            goto cleanup;
+        }
+
+        if (VIR_ALLOC(dom->def) < 0)
+            goto no_memory;
 
         if (STREQ(status, "stopped"))
             dom->state = VIR_DOMAIN_SHUTOFF;
index e7813bd1c3cbe81374f414d2fef1824f97acaafe..1030d176375838c622099ba791c5e11c20a53661 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "internal.h"
 #include "domain_conf.h"
+#include "threads.h"
 
 enum { OPENVZ_WARN, OPENVZ_ERR };
 
@@ -53,7 +54,7 @@ enum { OPENVZ_WARN, OPENVZ_ERR };
 #define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1)
 
 struct openvz_driver {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virCapsPtr caps;
     virDomainObjList domains;
index 597a06a97f2c885eed1f10d1ff0beab91782ca62..4e83bedd3cf3e7a89f32e657e11b2cba244a59b9 100644 (file)
@@ -70,12 +70,12 @@ static int openvzDomainSetVcpusInternal(virConnectPtr conn, virDomainObjPtr vm,
 
 static void openvzDriverLock(struct openvz_driver *driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 
 static void openvzDriverUnlock(struct openvz_driver *driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 struct openvz_driver ovz_driver;
index 70d9394e38603b63378e6c608b7fb3bb2bed878a..db2491cdccf12ae9c0bd0f6ddb527ed5e7630569 100644 (file)
@@ -32,6 +32,7 @@
 #include "network_conf.h"
 #include "domain_conf.h"
 #include "domain_event.h"
+#include "threads.h"
 
 #define qemudDebug(fmt, ...) do {} while(0)
 
@@ -51,7 +52,7 @@ enum qemud_cmd_flags {
 
 /* Main driver state */
 struct qemud_driver {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     unsigned int qemuVersion;
     int nextvmid;
index f5168e1eaab15e5e76b4aab1bc65435a0cbfd456..1619154ea1b59e7e51b052a20422e518ba72f5c0 100644 (file)
@@ -78,11 +78,11 @@ static int qemudShutdown(void);
 
 static void qemuDriverLock(struct qemud_driver *driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 static void qemuDriverUnlock(struct qemud_driver *driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 static int qemudSetCloseExec(int fd) {
@@ -273,7 +273,11 @@ qemudStartup(void) {
     if (VIR_ALLOC(qemu_driver) < 0)
         return -1;
 
-    pthread_mutex_init(&qemu_driver->lock, NULL);
+    if (virMutexInit(&qemu_driver->lock) < 0) {
+        qemudLog(QEMUD_ERROR, "%s", _("cannot initialize mutex"));
+        VIR_FREE(qemu_driver);
+        return -1;
+    }
     qemuDriverLock(qemu_driver);
 
     /* Don't have a dom0 so start from 1 */
@@ -482,6 +486,7 @@ qemudShutdown(void) {
         brShutdown(qemu_driver->brctl);
 
     qemuDriverUnlock(qemu_driver);
+    virMutexDestroy(&qemu_driver->lock);
     VIR_FREE(qemu_driver);
 
     return 0;
index 2cd7eeceb85c11cd2a12ec4ba3713fd85a91f949..62b4196c0072d813fab2e37c77cac265f8c89324 100644 (file)
@@ -297,6 +297,9 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj) {
 
     VIR_FREE(obj->configFile);
     VIR_FREE(obj->autostartLink);
+
+    virMutexDestroy(&obj->lock);
+
     VIR_FREE(obj);
 }
 
@@ -1259,13 +1262,19 @@ virStoragePoolObjAssignDef(virConnectPtr conn,
         return NULL;
     }
 
-    pthread_mutex_init(&pool->lock, NULL);
+    if (virMutexInit(&pool->lock) < 0) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                              "%s", _("cannot initialize mutex"));
+        VIR_FREE(pool);
+        return NULL;
+    }
     virStoragePoolObjLock(pool);
     pool->active = 0;
     pool->def = def;
 
     if (VIR_REALLOC_N(pools->objs, pools->count+1) < 0) {
         pool->def = NULL;
+        virStoragePoolObjUnlock(pool);
         virStoragePoolObjFree(pool);
         virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL);
         return NULL;
@@ -1530,23 +1539,12 @@ char *virStoragePoolSourceListFormat(virConnectPtr conn,
 }
 
 
-#ifdef HAVE_PTHREAD_H
-
 void virStoragePoolObjLock(virStoragePoolObjPtr obj)
 {
-    pthread_mutex_lock(&obj->lock);
+    virMutexLock(&obj->lock);
 }
 
 void virStoragePoolObjUnlock(virStoragePoolObjPtr obj)
 {
-    pthread_mutex_unlock(&obj->lock);
+    virMutexUnlock(&obj->lock);
 }
-#else
-void virStoragePoolObjLock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-
-void virStoragePoolObjUnlock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
-{
-}
-#endif
index 7956354cbca1d1d539829be1323dd8c6b026e4e3..7171823cf947e8de9ddcd3da36ece304dcf954ac 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "internal.h"
 #include "util.h"
+#include "threads.h"
 
 /* Shared structs */
 
@@ -223,7 +224,7 @@ typedef struct _virStoragePoolObj virStoragePoolObj;
 typedef virStoragePoolObj *virStoragePoolObjPtr;
 
 struct _virStoragePoolObj {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     char *configFile;
     char *autostartLink;
@@ -250,7 +251,7 @@ typedef struct _virStorageDriverState virStorageDriverState;
 typedef virStorageDriverState *virStorageDriverStatePtr;
 
 struct _virStorageDriverState {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     virStoragePoolObjList pools;
 
index d925eae13974b65555af993e53946bb20fe2c1db..4bcbc361c6b2e865034f9b19f54752c4da008506 100644 (file)
@@ -49,11 +49,11 @@ static int storageDriverShutdown(void);
 
 static void storageDriverLock(virStorageDriverStatePtr driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 static void storageDriverUnlock(virStorageDriverStatePtr driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 static void
@@ -113,7 +113,10 @@ storageDriverStartup(void) {
     if (VIR_ALLOC(driverState) < 0)
         return -1;
 
-    pthread_mutex_init(&driverState->lock, NULL);
+    if (virMutexInit(&driverState->lock) < 0) {
+        VIR_FREE(driverState);
+        return -1;
+    }
     storageDriverLock(driverState);
 
     if (!uid) {
@@ -266,6 +269,7 @@ storageDriverShutdown(void) {
     VIR_FREE(driverState->configDir);
     VIR_FREE(driverState->autostartDir);
     storageDriverUnlock(driverState);
+    virMutexDestroy(&driverState->lock);
     VIR_FREE(driverState);
 
     return 0;
index 7a09c5d94c81e9f98e485d7410854d9269992819..e72bddebec30241bfe4d911f45400a75cd89d9a9 100644 (file)
@@ -44,6 +44,7 @@
 #include "domain_conf.h"
 #include "storage_conf.h"
 #include "xml.h"
+#include "threads.h"
 
 #define MAX_CPUS 128
 
@@ -58,7 +59,7 @@ typedef struct _testCell *testCellPtr;
 #define MAX_CELLS 128
 
 struct _testConn {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     char path[PATH_MAX];
     int nextDomID;
@@ -93,20 +94,15 @@ static const virNodeInfo defaultNodeInfo = {
         virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \
                                __FUNCTION__, __LINE__, fmt)
 
-#ifdef HAVE_THREAD_H
 static void testDriverLock(testConnPtr driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 
 static void testDriverUnlock(testConnPtr driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
-#else
-static void testDriverLock(testConnPtr driver ATTRIBUTE_UNUSED) {}
-static void testDriverUnlock(testConnPtr driver ATTRIBUTE_UNUSED) {}
-#endif
 
 static virCapsPtr
 testBuildCapabilities(virConnectPtr conn) {
@@ -216,9 +212,15 @@ static int testOpenDefault(virConnectPtr conn) {
         testError(conn, VIR_ERR_NO_MEMORY, "testConn");
         return VIR_DRV_OPEN_ERROR;
     }
-    conn->privateData = privconn;
-    pthread_mutex_init(&privconn->lock, NULL);
+    if (virMutexInit(&privconn->lock) < 0) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("cannot initialize mutex"));
+        VIR_FREE(privconn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+
     testDriverLock(privconn);
+    conn->privateData = privconn;
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("getting time of day"));
@@ -282,6 +284,7 @@ static int testOpenDefault(virConnectPtr conn) {
     virStoragePoolObjUnlock(poolobj);
 
     testDriverUnlock(privconn);
+
     return VIR_DRV_OPEN_SUCCESS;
 
 error:
@@ -290,6 +293,7 @@ error:
     virStoragePoolObjListFree(&privconn->pools);
     virCapabilitiesFree(privconn->caps);
     testDriverUnlock(privconn);
+    conn->privateData = NULL;
     VIR_FREE(privconn);
     return VIR_DRV_OPEN_ERROR;
 }
@@ -335,9 +339,15 @@ static int testOpenFromFile(virConnectPtr conn,
         testError(NULL, VIR_ERR_NO_MEMORY, "testConn");
         return VIR_DRV_OPEN_ERROR;
     }
-    conn->privateData = privconn;
-    pthread_mutex_init(&privconn->lock, NULL);
+    if (virMutexInit(&privconn->lock) < 0) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("cannot initialize mutex"));
+        VIR_FREE(privconn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+
     testDriverLock(privconn);
+    conn->privateData = privconn;
 
     if (!(privconn->caps = testBuildCapabilities(conn)))
         goto error;
@@ -643,6 +653,7 @@ static int testClose(virConnectPtr conn)
     virNetworkObjListFree(&privconn->networks);
     virStoragePoolObjListFree(&privconn->pools);
     testDriverUnlock(privconn);
+    virMutexDestroy(&privconn->lock);
 
     VIR_FREE (privconn);
     conn->privateData = NULL;
diff --git a/src/threads-pthread.c b/src/threads-pthread.c
new file mode 100644 (file)
index 0000000..4e00bc5
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * threads-pthread.c: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+
+/* Nothing special required for pthreads */
+int virThreadInitialize(void)
+{
+    return 0;
+}
+
+void virThreadOnExit(void)
+{
+}
+
+
+int virMutexInit(virMutexPtr m)
+{
+    if (pthread_mutex_init(&m->lock, NULL) != 0) {
+        errno = EINVAL;
+        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)
+{
+    if (pthread_cond_init(&c->cond, NULL) != 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
+}
+
+int virCondDestroy(virCondPtr c)
+{
+    if (pthread_cond_destroy(&c->cond) != 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
+}
+
+int virCondWait(virCondPtr c, virMutexPtr m)
+{
+    if (pthread_cond_wait(&c->cond, &m->lock) != 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
+}
+
+void virCondSignal(virCondPtr c)
+{
+    pthread_cond_signal(&c->cond);
+}
+
+void virCondBroadcast(virCondPtr c)
+{
+    pthread_cond_broadcast(&c->cond);
+}
+
+
+int virThreadLocalInit(virThreadLocalPtr l,
+                       virThreadLocalCleanup c)
+{
+    if (pthread_key_create(&l->key, c) != 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
+}
+
+void *virThreadLocalGet(virThreadLocalPtr l)
+{
+    return pthread_getspecific(l->key);
+}
+
+void virThreadLocalSet(virThreadLocalPtr l, void *val)
+{
+    pthread_setspecific(l->key, val);
+}
diff --git a/src/threads-pthread.h b/src/threads-pthread.h
new file mode 100644 (file)
index 0000000..6404d1d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * threads.c: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include "internal.h"
+
+#include <pthread.h>
+
+struct virMutex {
+    pthread_mutex_t lock;
+};
+
+struct virCond {
+    pthread_cond_t cond;
+};
+
+struct virThreadLocal {
+    pthread_key_t key;
+};
diff --git a/src/threads-win32.c b/src/threads-win32.c
new file mode 100644 (file)
index 0000000..10233b0
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * threads-win32.c: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include "memory.h"
+
+struct virThreadLocalData {
+    DWORD key;
+    virThreadLocalCleanup cleanup;
+};
+typedef struct virThreadLocalData virThreadLocalData;
+typedef virThreadLocalData *virThreadLocalDataPtr;
+
+virMutex virThreadLocalLock;
+unsigned int virThreadLocalCount = 0;
+virThreadLocalDataPtr virThreadLocalList = NULL;
+
+
+virThreadLocal virCondEvent;
+
+void virCondEventCleanup(void *data);
+
+int virThreadInitialize(void)
+{
+    virMutexInit(&virThreadLocalLock);
+    virThreadLocalInit(&virCondEvent, virCondEventCleanup);
+
+    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 virMutexInit(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;
+        }
+        virThreadLocalSet(&virCondEvent, event);
+    }
+
+    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;
+}
+
+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);
+}
+
+
+
+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);
+}
+
+void virThreadLocalSet(virThreadLocalPtr l, void *val)
+{
+    TlsSetValue(l->key, val);
+}
diff --git a/src/threads-win32.h b/src/threads-win32.h
new file mode 100644 (file)
index 0000000..783d91d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * threads-win32.h basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include "internal.h"
+
+#include <windows.h>
+
+struct virMutex {
+    HANDLE lock;
+};
+
+struct virCond {
+    virMutex lock;
+    unsigned int nwaiters;
+    HANDLE *waiters;
+};
+
+
+struct virThreadLocal {
+    DWORD key;
+};
diff --git a/src/threads.c b/src/threads.c
new file mode 100644 (file)
index 0000000..d61b743
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * threads.c: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include "threads.h"
+
+#ifdef HAVE_PTHREAD_H
+#include "threads-pthread.c"
+#else
+#ifdef WIN32
+#include "threads-win32.c"
+#else
+#error "Either pthreads or Win32 threads are required"
+#endif
+#endif
diff --git a/src/threads.h b/src/threads.h
new file mode 100644 (file)
index 0000000..62239b7
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * threads.h: basic thread synchronization primitives
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#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;
+
+
+int virThreadInitialize(void) ATTRIBUTE_RETURN_CHECK;
+void virThreadOnExit(void);
+
+int virMutexInit(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;
+
+int virCondWait(virCondPtr c, virMutexPtr m) 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);
+void virThreadLocalSet(virThreadLocalPtr l, void*);
+
+#ifdef HAVE_PTHREAD_H
+#include "threads-pthread.h"
+#else
+#ifdef WIN32
+#include "threads-win32.h"
+#else
+#error "Either pthreads or Win32 threads are required"
+#endif
+#endif
+
+#endif
index f6cfe5ea937149d11956436fc3e61ff9b5636530..f7846e056d85f46e1288562955d80f5ce97a8fb2 100644 (file)
@@ -30,6 +30,7 @@
 #include "network_conf.h"
 #include "domain_conf.h"
 #include "virterror_internal.h"
+#include "threads.h"
 
 #define umlDebug(fmt, ...) do {} while(0)
 
@@ -39,7 +40,7 @@
 
 /* Main driver state */
 struct uml_driver {
-    PTHREAD_MUTEX_T(lock);
+    virMutex lock;
 
     unsigned int umlVersion;
     int nextvmid;
index 38f74551d4d1d4e7f4a94b8ca44d6224c06174ab..91bb6e5aebdef7a0a7a0cf3ddd0e45cdedf2e69b 100644 (file)
@@ -74,11 +74,11 @@ static int umlShutdown(void);
 
 static void umlDriverLock(struct uml_driver *driver)
 {
-    pthread_mutex_lock(&driver->lock);
+    virMutexLock(&driver->lock);
 }
 static void umlDriverUnlock(struct uml_driver *driver)
 {
-    pthread_mutex_unlock(&driver->lock);
+    virMutexUnlock(&driver->lock);
 }
 
 
@@ -314,7 +314,10 @@ umlStartup(void) {
     if (VIR_ALLOC(uml_driver) < 0)
         return -1;
 
-    pthread_mutex_init(&uml_driver->lock, NULL);
+    if (virMutexInit(&uml_driver->lock) < 0) {
+        VIR_FREE(uml_driver);
+        return -1;
+    }
     umlDriverLock(uml_driver);
 
     /* Don't have a dom0 so start from 1 */
@@ -501,6 +504,7 @@ umlShutdown(void) {
         brShutdown(uml_driver->brctl);
 
     umlDriverUnlock(uml_driver);
+    virMutexDestroy(&uml_driver->lock);
     VIR_FREE(uml_driver);
 
     return 0;