From 4dac0a1105b3d4bc4b4af9942be3849ffb298ef3 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 15 Jan 2009 19:56:05 +0000 Subject: [PATCH] Generic internal threads API --- ChangeLog | 24 +++++ po/POTFILES.in | 1 + proxy/Makefile.am | 1 + qemud/qemud.c | 80 ++++++++------ qemud/qemud.h | 7 +- qemud/remote.c | 72 ++++++------- src/Makefile.am | 7 +- src/datatypes.c | 77 +++++++------- src/datatypes.h | 4 +- src/domain_conf.c | 26 ++--- src/domain_conf.h | 3 +- src/internal.h | 13 --- src/libvirt.c | 41 +++++++ src/libvirt_private.syms | 12 +++ src/logging.c | 14 ++- src/lxc_conf.h | 3 +- src/lxc_driver.c | 10 +- src/network_conf.c | 25 ++--- src/network_conf.h | 3 +- src/network_driver.c | 12 ++- src/node_device.c | 4 +- src/node_device_conf.c | 27 ++--- src/node_device_conf.h | 5 +- src/node_device_devkit.c | 8 +- src/node_device_hal.c | 6 +- src/openvz_conf.c | 13 ++- src/openvz_conf.h | 3 +- src/openvz_driver.c | 4 +- src/qemu_conf.h | 3 +- src/qemu_driver.c | 11 +- src/storage_conf.c | 26 +++-- src/storage_conf.h | 5 +- src/storage_driver.c | 10 +- src/test.c | 35 +++--- src/threads-pthread.c | 117 ++++++++++++++++++++ src/threads-pthread.h | 36 +++++++ src/threads-win32.c | 223 +++++++++++++++++++++++++++++++++++++++ src/threads-win32.h | 39 +++++++ src/threads.c | 34 ++++++ src/threads.h | 72 +++++++++++++ src/uml_conf.h | 3 +- src/uml_driver.c | 10 +- 42 files changed, 893 insertions(+), 236 deletions(-) create mode 100644 src/threads-pthread.c create mode 100644 src/threads-pthread.h create mode 100644 src/threads-win32.c create mode 100644 src/threads-win32.h create mode 100644 src/threads.c create mode 100644 src/threads.h diff --git a/ChangeLog b/ChangeLog index 80f4be0359..4b10e2d745 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Thu Jan 15 19:54:19 GMT 2009 Daniel P. Berrange + + 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 * src/util.c: Implement virKill() for Win32 platform diff --git a/po/POTFILES.in b/po/POTFILES.in index 26617a06a9..4a434ff2f5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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 diff --git a/proxy/Makefile.am b/proxy/Makefile.am index b680a1b306..d4a2fc495a 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -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 \ diff --git a/qemud/qemud.c b/qemud/qemud.c index 6a2db78c89..5eec6c0590 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -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 diff --git a/qemud/qemud.h b/qemud/qemud.h index 42066cbf98..12897a12bf 100644 --- a/qemud/qemud.h +++ b/qemud/qemud.h @@ -46,6 +46,7 @@ #include #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; diff --git a/qemud/remote.c b/qemud/remote.c index a5a84cceb1..25a6f4bd16 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -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; } diff --git a/src/Makefile.am b/src/Makefile.am index dd7dea8f34..8989a8fb0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/datatypes.c b/src/datatypes.c index 82acd080df..f602ef230e 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -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); } diff --git a/src/datatypes.h b/src/datatypes.h index 6512537896..d1bc88f761 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -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 */ diff --git a/src/domain_conf.c b/src/domain_conf.c index 8bb51f7f06..4250d81c76 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -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 */ diff --git a/src/domain_conf.h b/src/domain_conf.h index 7320609fae..1e5c10369a 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -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; diff --git a/src/internal.h b/src/internal.h index 696e5db1a3..adb65076ea 100644 --- a/src/internal.h +++ b/src/internal.h @@ -13,19 +13,6 @@ #include #endif -#ifdef HAVE_PTHREAD_H -#include -#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. diff --git a/src/libvirt.c b/src/libvirt.c index a96eecd40b..900bc62d87 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -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 /** diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6b48ea4f39..c76b6c2376 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -261,6 +261,18 @@ virStoragePoolObjLock; virStoragePoolObjUnlock; +# threads.h +virMutexInit; +virMutexDestroy; +virMutexLock; +virMutexUnlock; + +virCondInit; +virCondDestroy; +virCondWait; +virCondSignal; +virCondBroadcast; + # util.h virFileReadAll; virStrToLong_i; diff --git a/src/logging.c b/src/logging.c index 8fb64286ca..d6bd22aa8b 100644 --- a/src/logging.c +++ b/src/logging.c @@ -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; } diff --git a/src/lxc_conf.h b/src/lxc_conf.h index 3b52f39a9a..b3d2a8aaef 100644 --- a/src/lxc_conf.h +++ b/src/lxc_conf.h @@ -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; diff --git a/src/lxc_driver.c b/src/lxc_driver.c index 13afae0bc4..2e9625a619 100644 --- a/src/lxc_driver.c +++ b/src/lxc_driver.c @@ -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; diff --git a/src/network_conf.c b/src/network_conf.c index b0c16e6129..410f255cee 100644 --- a/src/network_conf.c +++ b/src/network_conf.c @@ -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); + virMutexUnlock(&obj->lock); } -#else -void virNetworkObjLock(virNetworkObjPtr obj ATTRIBUTE_UNUSED) -{ -} - -void virNetworkObjUnlock(virNetworkObjPtr obj ATTRIBUTE_UNUSED) -{ -} - -#endif diff --git a/src/network_conf.h b/src/network_conf.h index 47bfc6e307..733ad51922 100644 --- a/src/network_conf.h +++ b/src/network_conf.h @@ -29,6 +29,7 @@ #include #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; diff --git a/src/network_driver.c b/src/network_driver.c index 04671aa83c..85d83ebce6 100644 --- a/src/network_driver.c +++ b/src/network_driver.c @@ -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); diff --git a/src/node_device.c b/src/node_device.c index 753b9b99bb..9586fa6330 100644 --- a/src/node_device.c +++ b/src/node_device.c @@ -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, diff --git a/src/node_device_conf.c b/src/node_device_conf.c index 9645c8917b..ff022b7b91 100644 --- a/src/node_device_conf.c +++ b/src/node_device_conf.c @@ -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); + virMutexUnlock(&obj->lock); } -#else - -void virNodeDeviceObjLock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED) -{ -} - -void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED) -{ -} - -#endif diff --git a/src/node_device_conf.h b/src/node_device_conf.h index 15a0757c04..202475595c 100644 --- a/src/node_device_conf.h +++ b/src/node_device_conf.h @@ -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 */ diff --git a/src/node_device_devkit.c b/src/node_device_devkit.c index 199143c3f8..9e3fa6f191 100644 --- a/src/node_device_devkit.c +++ b/src/node_device_devkit.c @@ -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; } diff --git a/src/node_device_hal.c b/src/node_device_hal.c index 3449ee0f7a..cb4f86b14e 100644 --- a/src/node_device_hal.c +++ b/src/node_device_hal.c @@ -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; } diff --git a/src/openvz_conf.c b/src/openvz_conf.c index 6fa02125f4..54474b753d 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -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; diff --git a/src/openvz_conf.h b/src/openvz_conf.h index e7813bd1c3..1030d17637 100644 --- a/src/openvz_conf.h +++ b/src/openvz_conf.h @@ -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; diff --git a/src/openvz_driver.c b/src/openvz_driver.c index 597a06a97f..4e83bedd3c 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -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; diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 70d9394e38..db2491cdcc 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -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; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index f5168e1eaa..1619154ea1 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -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; diff --git a/src/storage_conf.c b/src/storage_conf.c index 2cd7eeceb8..62b4196c00 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -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 diff --git a/src/storage_conf.h b/src/storage_conf.h index 7956354cbc..7171823cf9 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -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; diff --git a/src/storage_driver.c b/src/storage_driver.c index d925eae139..4bcbc361c6 100644 --- a/src/storage_driver.c +++ b/src/storage_driver.c @@ -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; diff --git a/src/test.c b/src/test.c index 7a09c5d94c..e72bddebec 100644 --- a/src/test.c +++ b/src/test.c @@ -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 index 0000000000..4e00bc5806 --- /dev/null +++ b/src/threads-pthread.c @@ -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 + + +/* 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 index 0000000000..6404d1dccb --- /dev/null +++ b/src/threads-pthread.h @@ -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 + +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 index 0000000000..10233b033d --- /dev/null +++ b/src/threads-win32.c @@ -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 + +#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 index 0000000000..783d91d7eb --- /dev/null +++ b/src/threads-win32.h @@ -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 + +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 index 0000000000..d61b74395a --- /dev/null +++ b/src/threads.c @@ -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 + +#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 index 0000000000..62239b711d --- /dev/null +++ b/src/threads.h @@ -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 diff --git a/src/uml_conf.h b/src/uml_conf.h index f6cfe5ea93..f7846e056d 100644 --- a/src/uml_conf.h +++ b/src/uml_conf.h @@ -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; diff --git a/src/uml_driver.c b/src/uml_driver.c index 38f74551d4..91bb6e5aeb 100644 --- a/src/uml_driver.c +++ b/src/uml_driver.c @@ -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(¨_driver->lock, NULL); + if (virMutexInit(¨_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(¨_driver->lock); VIR_FREE(uml_driver); return 0;