Generic internal threads API

This commit is contained in:
Daniel P. Berrange 2009-01-15 19:56:05 +00:00
parent 52e51d278e
commit 4dac0a1105
42 changed files with 893 additions and 236 deletions

View File

@ -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> Thu Jan 15 19:39:19 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
* src/util.c: Implement virKill() for Win32 platform * src/util.c: Implement virKill() for Win32 platform

View File

@ -14,6 +14,7 @@ src/lxc_driver.c
src/network_conf.c src/network_conf.c
src/network_driver.c src/network_driver.c
src/node_device.c src/node_device.c
src/node_device_conf.c
src/openvz_conf.c src/openvz_conf.c
src/openvz_driver.c src/openvz_driver.c
src/proxy_internal.c src/proxy_internal.c

View File

@ -12,6 +12,7 @@ libexec_PROGRAMS = libvirt_proxy
libvirt_proxy_SOURCES = libvirt_proxy.c @top_srcdir@/src/xend_internal.c \ 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/xen_internal.c @top_srcdir@/src/virterror.c \
@top_srcdir@/src/sexpr.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/xs_internal.c @top_srcdir@/src/buf.c \
@top_srcdir@/src/capabilities.c \ @top_srcdir@/src/capabilities.c \
@top_srcdir@/src/memory.c \ @top_srcdir@/src/memory.c \

View File

@ -268,11 +268,11 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
siginfo_t siginfo; siginfo_t siginfo;
int ret; int ret;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
if (saferead(server->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) { if (saferead(server->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
VIR_ERROR(_("Failed to read from signal pipe: %s"), strerror(errno)); VIR_ERROR(_("Failed to read from signal pipe: %s"), strerror(errno));
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
return; return;
} }
@ -300,7 +300,7 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
if (ret != 0) if (ret != 0)
server->shutdown = 1; server->shutdown = 1;
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
} }
int qemudSetCloseExec(int fd) { int qemudSetCloseExec(int fd) {
@ -688,9 +688,14 @@ static struct qemud_server *qemudInitialize(int sigread) {
return NULL; 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); VIR_FREE(server);
return NULL;
} }
server->sigread = sigread; server->sigread = sigread;
@ -1117,8 +1122,11 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
if (VIR_ALLOC(client) < 0) if (VIR_ALLOC(client) < 0)
goto cleanup; 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; goto cleanup;
}
client->magic = QEMUD_CLIENT_MAGIC; client->magic = QEMUD_CLIENT_MAGIC;
client->fd = fd; client->fd = fd;
@ -1233,12 +1241,12 @@ static struct qemud_client *qemudPendingJob(struct qemud_server *server)
{ {
int i; int i;
for (i = 0 ; i < server->nclients ; 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) { if (server->clients[i]->mode == QEMUD_MODE_WAIT_DISPATCH) {
/* Delibrately don't unlock client - caller wants the lock */ /* Delibrately don't unlock client - caller wants the lock */
return server->clients[i]; return server->clients[i];
} }
pthread_mutex_unlock(&server->clients[i]->lock); virMutexUnlock(&server->clients[i]->lock);
} }
return NULL; return NULL;
} }
@ -1250,10 +1258,14 @@ static void *qemudWorker(void *data)
while (1) { while (1) {
struct qemud_client *client; struct qemud_client *client;
int len; int len;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
while ((client = qemudPendingJob(server)) == NULL) while ((client = qemudPendingJob(server)) == NULL) {
pthread_cond_wait(&server->job, &server->lock); if (virCondWait(&server->job, &server->lock) < 0) {
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
return NULL;
}
}
virMutexUnlock(&server->lock);
/* We own a locked client now... */ /* We own a locked client now... */
client->mode = QEMUD_MODE_IN_DISPATCH; client->mode = QEMUD_MODE_IN_DISPATCH;
@ -1271,8 +1283,8 @@ static void *qemudWorker(void *data)
qemudDispatchClientFailure(server, client); qemudDispatchClientFailure(server, client);
client->refs--; client->refs--;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
} }
} }
@ -1444,7 +1456,7 @@ static void qemudDispatchClientRead(struct qemud_server *server, struct qemud_cl
if (qemudRegisterClientEvent(server, client, 1) < 0) if (qemudRegisterClientEvent(server, client, 1) < 0)
qemudDispatchClientFailure(server, client); qemudDispatchClientFailure(server, client);
pthread_cond_signal(&server->job); virCondSignal(&server->job);
break; break;
} }
@ -1627,7 +1639,7 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
struct qemud_client *client = NULL; struct qemud_client *client = NULL;
int i; int i;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
for (i = 0 ; i < server->nclients ; i++) { for (i = 0 ; i < server->nclients ; i++) {
if (server->clients[i]->watch == watch) { if (server->clients[i]->watch == watch) {
@ -1637,12 +1649,12 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
} }
if (!client) { if (!client) {
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
return; return;
} }
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
if (client->fd != fd) if (client->fd != fd)
return; return;
@ -1653,7 +1665,7 @@ qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
qemudDispatchClientRead(server, client); qemudDispatchClientRead(server, client);
else else
qemudDispatchClientFailure(server, client); qemudDispatchClientFailure(server, client);
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
} }
static int qemudRegisterClientEvent(struct qemud_server *server, 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_server *server = (struct qemud_server *)opaque;
struct qemud_socket *sock; struct qemud_socket *sock;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
sock = server->sockets; sock = server->sockets;
@ -1717,7 +1729,7 @@ qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
if (sock && sock->fd == fd && events) if (sock && sock->fd == fd && events)
qemudDispatchServer(server, sock); 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 timerid = -1;
int ret = -1, i; int ret = -1, i;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
server->nworkers = min_workers; server->nworkers = min_workers;
if (VIR_ALLOC_N(server->workers, server->nworkers) < 0) { 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); DEBUG("Scheduling shutdown timer %d", timerid);
} }
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
if (qemudOneLoop() < 0) if (qemudOneLoop() < 0)
break; break;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
reprocess: reprocess:
for (i = 0 ; i < server->nclients ; i++) { for (i = 0 ; i < server->nclients ; i++) {
int inactive; int inactive;
pthread_mutex_lock(&server->clients[i]->lock); virMutexLock(&server->clients[i]->lock);
inactive = server->clients[i]->fd == -1 inactive = server->clients[i]->fd == -1
&& server->clients[i]->refs == 0; && server->clients[i]->refs == 0;
pthread_mutex_unlock(&server->clients[i]->lock); virMutexUnlock(&server->clients[i]->lock);
if (inactive) { if (inactive) {
if (server->clients[i]->conn) if (server->clients[i]->conn)
virConnectClose(server->clients[i]->conn); virConnectClose(server->clients[i]->conn);
virMutexDestroy(&server->clients[i]->lock);
VIR_FREE(server->clients[i]); VIR_FREE(server->clients[i]);
server->nclients--; server->nclients--;
if (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++) { for (i = 0 ; i < server->nworkers ; i++) {
pthread_t thread = server->workers[i]; pthread_t thread = server->workers[i];
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
pthread_join(thread, NULL); pthread_join(thread, NULL);
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
} }
free(server->workers); free(server->workers);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
return ret; return ret;
} }
@ -1862,7 +1875,12 @@ static void qemudCleanup(struct qemud_server *server) {
virStateCleanup(); 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 /* Allocate an array of malloc'd strings from the config file, filename

View File

@ -46,6 +46,7 @@
#include <rpc/xdr.h> #include <rpc/xdr.h>
#include "remote_protocol.h" #include "remote_protocol.h"
#include "logging.h" #include "logging.h"
#include "threads.h"
#ifdef __GNUC__ #ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H #ifdef HAVE_ANSIDECL_H
@ -88,7 +89,7 @@ enum qemud_sock_type {
/* Stores the per-client connection state */ /* Stores the per-client connection state */
struct qemud_client { struct qemud_client {
PTHREAD_MUTEX_T(lock); virMutex lock;
int magic; int magic;
@ -149,8 +150,8 @@ struct qemud_socket {
/* Main server state */ /* Main server state */
struct qemud_server { struct qemud_server {
pthread_mutex_t lock; virMutex lock;
pthread_cond_t job; virCond job;
int nworkers; int nworkers;
pthread_t *workers; pthread_t *workers;

View File

@ -301,7 +301,7 @@ remoteDispatchClientRequest (struct qemud_server *server,
/* Call function. */ /* Call function. */
conn = client->conn; conn = client->conn;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
/* /*
* When the RPC handler is called: * When the RPC handler is called:
@ -315,9 +315,9 @@ remoteDispatchClientRequest (struct qemud_server *server,
*/ */
rv = (data->fn)(server, client, conn, &rerr, &args, &ret); rv = (data->fn)(server, client, conn, &rerr, &args, &ret);
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
xdr_free (data->args_filter, (char*)&args); xdr_free (data->args_filter, (char*)&args);
@ -412,9 +412,9 @@ remoteDispatchOpen (struct qemud_server *server,
return -1; return -1;
} }
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
name = args->name ? *args->name : NULL; name = args->name ? *args->name : NULL;
@ -433,7 +433,7 @@ remoteDispatchOpen (struct qemud_server *server,
remoteDispatchConnError(rerr, NULL); remoteDispatchConnError(rerr, NULL);
rc = client->conn ? 0 : -1; rc = client->conn ? 0 : -1;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return rc; return rc;
} }
@ -450,13 +450,13 @@ remoteDispatchClose (struct qemud_server *server ATTRIBUTE_UNUSED,
remote_error *rerr ATTRIBUTE_UNUSED, remote_error *rerr ATTRIBUTE_UNUSED,
void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED) void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED)
{ {
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
client->closing = 1; client->closing = 1;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
} }
@ -2472,11 +2472,11 @@ remoteDispatchAuthList (struct qemud_server *server,
remoteDispatchOOMError(rerr); remoteDispatchOOMError(rerr);
return -1; return -1;
} }
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
ret->types.types_val[0] = client->auth; ret->types.types_val[0] = client->auth;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
} }
@ -2535,9 +2535,9 @@ remoteDispatchAuthSaslInit (struct qemud_server *server,
socklen_t salen; socklen_t salen;
char *localAddr, *remoteAddr; char *localAddr, *remoteAddr;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
REMOTE_DEBUG("Initialize SASL auth %d", client->fd); REMOTE_DEBUG("Initialize SASL auth %d", client->fd);
if (client->auth != REMOTE_AUTH_SASL || if (client->auth != REMOTE_AUTH_SASL ||
@ -2663,13 +2663,13 @@ remoteDispatchAuthSaslInit (struct qemud_server *server,
goto authfail; goto authfail;
} }
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
authfail: authfail:
remoteDispatchAuthError(rerr); remoteDispatchAuthError(rerr);
error: error:
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return -1; return -1;
} }
@ -2787,9 +2787,9 @@ remoteDispatchAuthSaslStart (struct qemud_server *server,
unsigned int serveroutlen; unsigned int serveroutlen;
int err; int err;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
REMOTE_DEBUG("Start SASL auth %d", client->fd); REMOTE_DEBUG("Start SASL auth %d", client->fd);
if (client->auth != REMOTE_AUTH_SASL || if (client->auth != REMOTE_AUTH_SASL ||
@ -2851,13 +2851,13 @@ remoteDispatchAuthSaslStart (struct qemud_server *server,
client->auth = REMOTE_AUTH_NONE; client->auth = REMOTE_AUTH_NONE;
} }
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
authfail: authfail:
remoteDispatchAuthError(rerr); remoteDispatchAuthError(rerr);
error: error:
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return -1; return -1;
} }
@ -2874,9 +2874,9 @@ remoteDispatchAuthSaslStep (struct qemud_server *server,
unsigned int serveroutlen; unsigned int serveroutlen;
int err; int err;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
REMOTE_DEBUG("Step SASL auth %d", client->fd); REMOTE_DEBUG("Step SASL auth %d", client->fd);
if (client->auth != REMOTE_AUTH_SASL || if (client->auth != REMOTE_AUTH_SASL ||
@ -2939,13 +2939,13 @@ remoteDispatchAuthSaslStep (struct qemud_server *server,
client->auth = REMOTE_AUTH_NONE; client->auth = REMOTE_AUTH_NONE;
} }
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
authfail: authfail:
remoteDispatchAuthError(rerr); remoteDispatchAuthError(rerr);
error: error:
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return -1; return -1;
} }
@ -3011,9 +3011,9 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
DBusError err; DBusError err;
const char *action; const char *action;
pthread_mutex_lock(&server->lock); virMutexLock(&server->lock);
pthread_mutex_lock(&client->lock); virMutexLock(&client->lock);
pthread_mutex_unlock(&server->lock); virMutexUnlock(&server->lock);
action = client->readonly ? action = client->readonly ?
"org.libvirt.unix.monitor" : "org.libvirt.unix.monitor" :
@ -3091,12 +3091,12 @@ remoteDispatchAuthPolkit (struct qemud_server *server,
ret->complete = 1; ret->complete = 1;
client->auth = REMOTE_AUTH_NONE; client->auth = REMOTE_AUTH_NONE;
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return 0; return 0;
authfail: authfail:
remoteDispatchAuthError(rerr); remoteDispatchAuthError(rerr);
pthread_mutex_unlock(&client->lock); virMutexUnlock(&client->lock);
return -1; return -1;
} }

View File

@ -46,14 +46,19 @@ UTIL_SOURCES = \
event.c event.h \ event.c event.h \
hash.c hash.h \ hash.c hash.h \
iptables.c iptables.h \ iptables.c iptables.h \
logging.c logging.h \
memory.c memory.h \ memory.c memory.h \
qparams.c qparams.h \ qparams.c qparams.h \
threads.c threads.h \
threads-pthread.h \
threads-win32.h \
uuid.c uuid.h \ uuid.c uuid.h \
util.c util.h \ util.c util.h \
virterror.c virterror_internal.h \ virterror.c virterror_internal.h \
logging.c logging.h \
xml.c xml.h xml.c xml.h
EXTRA_DIST += threads-pthread.c threads-win32.c
# Internal generic driver infrastructure # Internal generic driver infrastructure
DRIVER_SOURCES = \ DRIVER_SOURCES = \
driver.c driver.h \ driver.c driver.h \

View File

@ -123,6 +123,11 @@ virGetConnect(void) {
virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection")); virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
goto failed; goto failed;
} }
if (virMutexInit(&ret->lock) < 0) {
VIR_FREE(ret);
goto failed;
}
ret->magic = VIR_CONNECT_MAGIC; ret->magic = VIR_CONNECT_MAGIC;
ret->driver = NULL; ret->driver = NULL;
ret->networkDriver = NULL; ret->networkDriver = NULL;
@ -144,8 +149,6 @@ virGetConnect(void) {
if (ret->nodeDevices == NULL) if (ret->nodeDevices == NULL)
goto failed; goto failed;
pthread_mutex_init(&ret->lock, NULL);
ret->refs = 1; ret->refs = 1;
return(ret); return(ret);
@ -162,7 +165,7 @@ failed:
if (ret->nodeDevices != NULL) if (ret->nodeDevices != NULL)
virHashFree(ret->nodeDevices, (virHashDeallocator) virNodeDeviceFree); virHashFree(ret->nodeDevices, (virHashDeallocator) virNodeDeviceFree);
pthread_mutex_destroy(&ret->lock); virMutexDestroy(&ret->lock);
VIR_FREE(ret); VIR_FREE(ret);
} }
return(NULL); return(NULL);
@ -197,8 +200,8 @@ virReleaseConnect(virConnectPtr conn) {
xmlFreeURI(conn->uri); xmlFreeURI(conn->uri);
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
pthread_mutex_destroy(&conn->lock); virMutexDestroy(&conn->lock);
VIR_FREE(conn); VIR_FREE(conn);
} }
@ -219,7 +222,7 @@ virUnrefConnect(virConnectPtr conn) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1); return(-1);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
DEBUG("unref connection %p %d", conn, conn->refs); DEBUG("unref connection %p %d", conn, conn->refs);
conn->refs--; conn->refs--;
refs = conn->refs; refs = conn->refs;
@ -228,7 +231,7 @@ virUnrefConnect(virConnectPtr conn) {
/* Already unlocked mutex */ /* Already unlocked mutex */
return (0); return (0);
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return (refs); return (refs);
} }
@ -253,7 +256,7 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
/* TODO search by UUID first as they are better differenciators */ /* 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); DEBUG("Existing hash entry %p: refs now %d", ret, ret->refs+1);
} }
ret->refs++; ret->refs++;
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return(ret); return(ret);
error: error:
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret); VIR_FREE(ret);
@ -337,7 +340,7 @@ virReleaseDomain(virDomainPtr domain) {
return; return;
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
} }
@ -358,7 +361,7 @@ virUnrefDomain(virDomainPtr domain) {
virLibConnError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1); return(-1);
} }
pthread_mutex_lock(&domain->conn->lock); virMutexLock(&domain->conn->lock);
DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs); DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs);
domain->refs--; domain->refs--;
refs = domain->refs; refs = domain->refs;
@ -368,7 +371,7 @@ virUnrefDomain(virDomainPtr domain) {
return (0); return (0);
} }
pthread_mutex_unlock(&domain->conn->lock); virMutexUnlock(&domain->conn->lock);
return (refs); return (refs);
} }
@ -393,7 +396,7 @@ virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
/* TODO search by UUID first as they are better differenciators */ /* 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++; conn->refs++;
} }
ret->refs++; ret->refs++;
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return(ret); return(ret);
error: error:
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret); VIR_FREE(ret);
@ -473,7 +476,7 @@ virReleaseNetwork(virNetworkPtr network) {
return; return;
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
} }
@ -494,7 +497,7 @@ virUnrefNetwork(virNetworkPtr network) {
virLibConnError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1); return(-1);
} }
pthread_mutex_lock(&network->conn->lock); virMutexLock(&network->conn->lock);
DEBUG("unref network %p %s %d", network, network->name, network->refs); DEBUG("unref network %p %s %d", network, network->name, network->refs);
network->refs--; network->refs--;
refs = network->refs; refs = network->refs;
@ -504,7 +507,7 @@ virUnrefNetwork(virNetworkPtr network) {
return (0); return (0);
} }
pthread_mutex_unlock(&network->conn->lock); virMutexUnlock(&network->conn->lock);
return (refs); return (refs);
} }
@ -530,7 +533,7 @@ virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uui
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
/* TODO search by UUID first as they are better differenciators */ /* 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++; conn->refs++;
} }
ret->refs++; ret->refs++;
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return(ret); return(ret);
error: error:
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret); VIR_FREE(ret);
@ -606,7 +609,7 @@ virReleaseStoragePool(virStoragePoolPtr pool) {
return; return;
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
} }
@ -627,7 +630,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1); return(-1);
} }
pthread_mutex_lock(&pool->conn->lock); virMutexLock(&pool->conn->lock);
DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs); DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs);
pool->refs--; pool->refs--;
refs = pool->refs; refs = pool->refs;
@ -637,7 +640,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
return (0); return (0);
} }
pthread_mutex_unlock(&pool->conn->lock); virMutexUnlock(&pool->conn->lock);
return (refs); return (refs);
} }
@ -664,7 +667,7 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
ret = (virStorageVolPtr) virHashLookup(conn->storageVols, key); ret = (virStorageVolPtr) virHashLookup(conn->storageVols, key);
if (ret == NULL) { if (ret == NULL) {
@ -695,11 +698,11 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
conn->refs++; conn->refs++;
} }
ret->refs++; ret->refs++;
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return(ret); return(ret);
error: error:
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret->pool); VIR_FREE(ret->pool);
@ -744,7 +747,7 @@ virReleaseStorageVol(virStorageVolPtr vol) {
return; return;
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
} }
@ -765,7 +768,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
virLibConnError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1); return(-1);
} }
pthread_mutex_lock(&vol->conn->lock); virMutexLock(&vol->conn->lock);
DEBUG("unref vol %p %s %d", vol, vol->name, vol->refs); DEBUG("unref vol %p %s %d", vol, vol->name, vol->refs);
vol->refs--; vol->refs--;
refs = vol->refs; refs = vol->refs;
@ -775,7 +778,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
return (0); return (0);
} }
pthread_mutex_unlock(&vol->conn->lock); virMutexUnlock(&vol->conn->lock);
return (refs); return (refs);
} }
@ -801,7 +804,7 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
} }
pthread_mutex_lock(&conn->lock); virMutexLock(&conn->lock);
ret = (virNodeDevicePtr) virHashLookup(conn->nodeDevices, name); ret = (virNodeDevicePtr) virHashLookup(conn->nodeDevices, name);
if (ret == NULL) { if (ret == NULL) {
@ -825,11 +828,11 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
conn->refs++; conn->refs++;
} }
ret->refs++; ret->refs++;
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
return(ret); return(ret);
error: error:
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
if (ret != NULL) { if (ret != NULL) {
VIR_FREE(ret->name); VIR_FREE(ret->name);
VIR_FREE(ret); VIR_FREE(ret);
@ -872,7 +875,7 @@ virReleaseNodeDevice(virNodeDevicePtr dev) {
return; return;
} }
pthread_mutex_unlock(&conn->lock); virMutexUnlock(&conn->lock);
} }
@ -889,7 +892,7 @@ int
virUnrefNodeDevice(virNodeDevicePtr dev) { virUnrefNodeDevice(virNodeDevicePtr dev) {
int refs; int refs;
pthread_mutex_lock(&dev->conn->lock); virMutexLock(&dev->conn->lock);
DEBUG("unref dev %p %s %d", dev, dev->name, dev->refs); DEBUG("unref dev %p %s %d", dev, dev->name, dev->refs);
dev->refs--; dev->refs--;
refs = dev->refs; refs = dev->refs;
@ -899,6 +902,6 @@ virUnrefNodeDevice(virNodeDevicePtr dev) {
return (0); return (0);
} }
pthread_mutex_unlock(&dev->conn->lock); virMutexUnlock(&dev->conn->lock);
return (refs); return (refs);
} }

View File

@ -26,7 +26,7 @@
#include "hash.h" #include "hash.h"
#include "driver.h" #include "driver.h"
#include "threads.h"
/** /**
* VIR_CONNECT_MAGIC: * VIR_CONNECT_MAGIC:
@ -125,7 +125,7 @@ struct _virConnect {
* count of any virDomain/virNetwork object associated with * count of any virDomain/virNetwork object associated with
* this connection * this connection
*/ */
PTHREAD_MUTEX_T (lock); virMutex lock;
virHashTablePtr domains; /* hash table for known domains */ virHashTablePtr domains; /* hash table for known domains */
virHashTablePtr networks; /* hash table for known domains */ virHashTablePtr networks; /* hash table for known domains */
virHashTablePtr storagePools;/* hash table for known storage pools */ virHashTablePtr storagePools;/* hash table for known storage pools */

View File

@ -433,6 +433,8 @@ void virDomainObjFree(virDomainObjPtr dom)
VIR_FREE(dom->monitorpath); VIR_FREE(dom->monitorpath);
VIR_FREE(dom->vcpupids); VIR_FREE(dom->vcpupids);
virMutexDestroy(&dom->lock);
VIR_FREE(dom); VIR_FREE(dom);
} }
@ -471,7 +473,13 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
return NULL; 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); virDomainObjLock(domain);
domain->state = VIR_DOMAIN_SHUTOFF; domain->state = VIR_DOMAIN_SHUTOFF;
domain->def = def; domain->def = def;
@ -3660,26 +3668,14 @@ const char *virDomainDefDefaultEmulator(virConnectPtr conn,
} }
#ifdef HAVE_PTHREAD_H
void virDomainObjLock(virDomainObjPtr obj) void virDomainObjLock(virDomainObjPtr obj)
{ {
pthread_mutex_lock(&obj->lock); virMutexLock(&obj->lock);
} }
void virDomainObjUnlock(virDomainObjPtr obj) 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 */ #endif /* ! PROXY */

View File

@ -31,6 +31,7 @@
#include "internal.h" #include "internal.h"
#include "capabilities.h" #include "capabilities.h"
#include "util.h" #include "util.h"
#include "threads.h"
/* Different types of hypervisor */ /* Different types of hypervisor */
/* NB: Keep in sync with virDomainVirtTypeToString impl */ /* NB: Keep in sync with virDomainVirtTypeToString impl */
@ -456,7 +457,7 @@ struct _virDomainDef {
typedef struct _virDomainObj virDomainObj; typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr; typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj { struct _virDomainObj {
PTHREAD_MUTEX_T(lock); virMutex lock;
int stdin_fd; int stdin_fd;
int stdout_fd; int stdout_fd;

View File

@ -13,19 +13,6 @@
#include <sys/syslimits.h> #include <sys/syslimits.h>
#endif #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 / /* The library itself is allowed to use deprecated functions /
* variables, so effectively undefine the deprecated attribute * variables, so effectively undefine the deprecated attribute
* which would otherwise be defined in libvirt.h. * which would otherwise be defined in libvirt.h.

View File

@ -253,8 +253,12 @@ virInitialize(void)
#endif #endif
if (initialized) if (initialized)
return(0); return(0);
initialized = 1; initialized = 1;
if (virThreadInitialize() < 0)
return -1;
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
debugEnv = getenv("LIBVIRT_DEBUG"); debugEnv = getenv("LIBVIRT_DEBUG");
if (debugEnv && *debugEnv && *debugEnv != '0') { if (debugEnv && *debugEnv && *debugEnv != '0') {
@ -316,6 +320,43 @@ virInitialize(void)
return(0); 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
/** /**

View File

@ -261,6 +261,18 @@ virStoragePoolObjLock;
virStoragePoolObjUnlock; virStoragePoolObjUnlock;
# threads.h
virMutexInit;
virMutexDestroy;
virMutexLock;
virMutexUnlock;
virCondInit;
virCondDestroy;
virCondWait;
virCondSignal;
virCondBroadcast;
# util.h # util.h
virFileReadAll; virFileReadAll;
virStrToLong_i; virStrToLong_i;

View File

@ -37,6 +37,7 @@
#include "logging.h" #include "logging.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "threads.h"
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
int debugFlag = 0; int debugFlag = 0;
@ -129,15 +130,15 @@ static int virLogResetOutputs(void);
/* /*
* Logs accesses must be serialized though a mutex * Logs accesses must be serialized though a mutex
*/ */
PTHREAD_MUTEX_T(virLogMutex); virMutex virLogMutex;
static void virLogLock(void) static void virLogLock(void)
{ {
pthread_mutex_lock(&virLogMutex); virMutexLock(&virLogMutex);
} }
static void virLogUnlock(void) static void virLogUnlock(void)
{ {
pthread_mutex_unlock(&virLogMutex); virMutexUnlock(&virLogMutex);
} }
@ -167,8 +168,11 @@ static int virLogInitialized = 0;
int virLogStartup(void) { int virLogStartup(void) {
if (virLogInitialized) if (virLogInitialized)
return(-1); return(-1);
if (virMutexInit(&virLogMutex) < 0)
return -1;
virLogInitialized = 1; virLogInitialized = 1;
pthread_mutex_init(&virLogMutex, NULL);
virLogLock(); virLogLock();
virLogLen = 0; virLogLen = 0;
virLogStart = 0; virLogStart = 0;
@ -214,7 +218,7 @@ void virLogShutdown(void) {
virLogStart = 0; virLogStart = 0;
virLogEnd = 0; virLogEnd = 0;
virLogUnlock(); virLogUnlock();
pthread_mutex_destroy(&virLogMutex); virMutexDestroy(&virLogMutex);
virLogInitialized = 0; virLogInitialized = 0;
} }

View File

@ -29,6 +29,7 @@
#include "internal.h" #include "internal.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "capabilities.h" #include "capabilities.h"
#include "threads.h"
#define LXC_CONFIG_DIR SYSCONF_DIR "/libvirt/lxc" #define LXC_CONFIG_DIR SYSCONF_DIR "/libvirt/lxc"
#define LXC_STATE_DIR LOCAL_STATE_DIR "/run/libvirt/lxc" #define LXC_STATE_DIR LOCAL_STATE_DIR "/run/libvirt/lxc"
@ -36,7 +37,7 @@
typedef struct __lxc_driver lxc_driver_t; typedef struct __lxc_driver lxc_driver_t;
struct __lxc_driver { struct __lxc_driver {
PTHREAD_MUTEX_T(lock); virMutex lock;
virCapsPtr caps; virCapsPtr caps;

View File

@ -57,11 +57,11 @@ static lxc_driver_t *lxc_driver = NULL;
static void lxcDriverLock(lxc_driver_t *driver) static void lxcDriverLock(lxc_driver_t *driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void lxcDriverUnlock(lxc_driver_t *driver) 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) { if (VIR_ALLOC(lxc_driver) < 0) {
return -1; return -1;
} }
pthread_mutex_init(&lxc_driver->lock, NULL); if (virMutexInit(&lxc_driver->lock) < 0) {
VIR_FREE(lxc_driver);
return -1;
}
lxcDriverLock(lxc_driver); lxcDriverLock(lxc_driver);
/* Check that this is a container enabled kernel */ /* 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->stateDir);
VIR_FREE(lxc_driver->logDir); VIR_FREE(lxc_driver->logDir);
lxcDriverUnlock(lxc_driver); lxcDriverUnlock(lxc_driver);
virMutexDestroy(&lxc_driver->lock);
VIR_FREE(lxc_driver); VIR_FREE(lxc_driver);
lxc_driver = NULL; lxc_driver = NULL;

View File

@ -126,6 +126,8 @@ void virNetworkObjFree(virNetworkObjPtr net)
VIR_FREE(net->configFile); VIR_FREE(net->configFile);
VIR_FREE(net->autostartLink); VIR_FREE(net->autostartLink);
virMutexDestroy(&net->lock);
VIR_FREE(net); VIR_FREE(net);
} }
@ -163,7 +165,12 @@ virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
return 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); virNetworkObjLock(network);
network->def = def; network->def = def;
@ -823,25 +830,13 @@ int virNetworkDeleteConfig(virConnectPtr conn,
return 0; return 0;
} }
#ifdef HAVE_PTHREAD_H
void virNetworkObjLock(virNetworkObjPtr obj) void virNetworkObjLock(virNetworkObjPtr obj)
{ {
pthread_mutex_lock(&obj->lock); virMutexLock(&obj->lock);
} }
void virNetworkObjUnlock(virNetworkObjPtr obj) 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

View File

@ -29,6 +29,7 @@
#include <libxml/xpath.h> #include <libxml/xpath.h>
#include "internal.h" #include "internal.h"
#include "threads.h"
/* 2 possible types of forwarding */ /* 2 possible types of forwarding */
enum virNetworkForwardType { enum virNetworkForwardType {
@ -82,7 +83,7 @@ struct _virNetworkDef {
typedef struct _virNetworkObj virNetworkObj; typedef struct _virNetworkObj virNetworkObj;
typedef virNetworkObj *virNetworkObjPtr; typedef virNetworkObj *virNetworkObjPtr;
struct _virNetworkObj { struct _virNetworkObj {
PTHREAD_MUTEX_T(lock); virMutex lock;
pid_t dnsmasqPid; pid_t dnsmasqPid;
unsigned int active : 1; unsigned int active : 1;

View File

@ -59,7 +59,7 @@
/* Main driver state */ /* Main driver state */
struct network_driver { struct network_driver {
PTHREAD_MUTEX_T(lock); virMutex lock;
virNetworkObjList networks; virNetworkObjList networks;
@ -73,11 +73,11 @@ struct network_driver {
static void networkDriverLock(struct network_driver *driver) static void networkDriverLock(struct network_driver *driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void networkDriverUnlock(struct network_driver *driver) static void networkDriverUnlock(struct network_driver *driver)
{ {
pthread_mutex_unlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
static int networkShutdown(void); static int networkShutdown(void);
@ -134,7 +134,10 @@ networkStartup(void) {
if (VIR_ALLOC(driverState) < 0) if (VIR_ALLOC(driverState) < 0)
goto error; goto error;
pthread_mutex_init(&driverState->lock, NULL); if (virMutexInit(&driverState->lock) < 0) {
VIR_FREE(driverState);
goto error;
}
networkDriverLock(driverState); networkDriverLock(driverState);
if (!uid) { if (!uid) {
@ -290,6 +293,7 @@ networkShutdown(void) {
iptablesContextFree(driverState->iptables); iptablesContextFree(driverState->iptables);
networkDriverUnlock(driverState); networkDriverUnlock(driverState);
virMutexDestroy(&driverState->lock);
VIR_FREE(driverState); VIR_FREE(driverState);

View File

@ -48,12 +48,12 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
void nodeDeviceLock(virDeviceMonitorStatePtr driver) void nodeDeviceLock(virDeviceMonitorStatePtr driver)
{ {
DEBUG("LOCK node %p", driver); DEBUG("LOCK node %p", driver);
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
void nodeDeviceUnlock(virDeviceMonitorStatePtr driver) void nodeDeviceUnlock(virDeviceMonitorStatePtr driver)
{ {
DEBUG("UNLOCK node %p", driver); DEBUG("UNLOCK node %p", driver);
pthread_mutex_unlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
static int nodeNumOfDevices(virConnectPtr conn, static int nodeNumOfDevices(virConnectPtr conn,

View File

@ -99,6 +99,8 @@ void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
if (dev->privateFree) if (dev->privateFree)
(*dev->privateFree)(dev->privateData); (*dev->privateFree)(dev->privateData);
virMutexDestroy(&dev->lock);
VIR_FREE(dev); VIR_FREE(dev);
} }
@ -128,12 +130,18 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn,
return NULL; 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); virNodeDeviceObjLock(device);
device->def = def; device->def = def;
if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) { if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) {
device->def = NULL; device->def = NULL;
virNodeDeviceObjUnlock(device);
virNodeDeviceObjFree(device); virNodeDeviceObjFree(device);
virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL); virNodeDeviceReportError(conn, VIR_ERR_NO_MEMORY, NULL);
return NULL; return NULL;
@ -408,26 +416,13 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
} }
#ifdef HAVE_PTHREAD_H
void virNodeDeviceObjLock(virNodeDeviceObjPtr obj) void virNodeDeviceObjLock(virNodeDeviceObjPtr obj)
{ {
pthread_mutex_lock(&obj->lock); virMutexLock(&obj->lock);
} }
void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj) 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

View File

@ -26,6 +26,7 @@
#include "internal.h" #include "internal.h"
#include "util.h" #include "util.h"
#include "threads.h"
enum virNodeDevCapType { enum virNodeDevCapType {
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */ /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
@ -142,7 +143,7 @@ struct _virNodeDeviceDef {
typedef struct _virNodeDeviceObj virNodeDeviceObj; typedef struct _virNodeDeviceObj virNodeDeviceObj;
typedef virNodeDeviceObj *virNodeDeviceObjPtr; typedef virNodeDeviceObj *virNodeDeviceObjPtr;
struct _virNodeDeviceObj { struct _virNodeDeviceObj {
PTHREAD_MUTEX_T(lock); virMutex lock;
virNodeDeviceDefPtr def; /* device definition */ virNodeDeviceDefPtr def; /* device definition */
void *privateData; /* driver-specific private data */ void *privateData; /* driver-specific private data */
@ -160,7 +161,7 @@ struct _virNodeDeviceObjList {
typedef struct _virDeviceMonitorState virDeviceMonitorState; typedef struct _virDeviceMonitorState virDeviceMonitorState;
typedef virDeviceMonitorState *virDeviceMonitorStatePtr; typedef virDeviceMonitorState *virDeviceMonitorStatePtr;
struct _virDeviceMonitorState { struct _virDeviceMonitorState {
PTHREAD_MUTEX_T(lock); virMutex lock;
virNodeDeviceObjList devs; /* currently-known devices */ virNodeDeviceObjList devs; /* currently-known devices */
void *privateData; /* driver-specific private data */ void *privateData; /* driver-specific private data */

View File

@ -298,7 +298,10 @@ static int devkitDeviceMonitorStartup(void)
if (VIR_ALLOC(driverState) < 0) if (VIR_ALLOC(driverState) < 0)
return -1; return -1;
pthread_mutex_init(&driverState->lock, NULL); if (virMutexInit(&driverState->lock) < 0) {
VIR_FREE(driverState);
return -1;
}
g_type_init(); g_type_init();
@ -375,7 +378,8 @@ static int devkitDeviceMonitorShutdown(void)
virNodeDeviceObjListFree(&driverState->devs); virNodeDeviceObjListFree(&driverState->devs);
if (devkit_client) if (devkit_client)
g_object_unref(devkit_client); g_object_unref(devkit_client);
nodeDeviceLock(driverState); nodeDeviceUnlock(driverState);
virMutexDestroy(&driveState->lock);
VIR_FREE(driverState); VIR_FREE(driverState);
return 0; return 0;
} }

View File

@ -678,7 +678,10 @@ static int halDeviceMonitorStartup(void)
if (VIR_ALLOC(driverState) < 0) if (VIR_ALLOC(driverState) < 0)
return -1; return -1;
pthread_mutex_init(&driverState->lock, NULL); if (virMutexInit(&driverState->lock) < 0) {
VIR_FREE(driverState);
return -1;
}
nodeDeviceLock(driverState); nodeDeviceLock(driverState);
/* Allocate and initialize a new HAL context */ /* 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_shutdown(hal_ctx, NULL);
(void)libhal_ctx_free(hal_ctx); (void)libhal_ctx_free(hal_ctx);
nodeDeviceUnlock(driverState); nodeDeviceUnlock(driverState);
virMutexDestroy(&driverState->lock);
VIR_FREE(driverState); VIR_FREE(driverState);
return 0; return 0;
} }

View File

@ -392,11 +392,18 @@ int openvzLoadDomains(struct openvz_driver *driver) {
goto cleanup; goto cleanup;
} }
if (VIR_ALLOC(dom) < 0 || if (VIR_ALLOC(dom) < 0)
VIR_ALLOC(dom->def) < 0)
goto no_memory; 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")) if (STREQ(status, "stopped"))
dom->state = VIR_DOMAIN_SHUTOFF; dom->state = VIR_DOMAIN_SHUTOFF;

View File

@ -30,6 +30,7 @@
#include "internal.h" #include "internal.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "threads.h"
enum { OPENVZ_WARN, OPENVZ_ERR }; 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) #define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1)
struct openvz_driver { struct openvz_driver {
PTHREAD_MUTEX_T(lock); virMutex lock;
virCapsPtr caps; virCapsPtr caps;
virDomainObjList domains; virDomainObjList domains;

View File

@ -70,12 +70,12 @@ static int openvzDomainSetVcpusInternal(virConnectPtr conn, virDomainObjPtr vm,
static void openvzDriverLock(struct openvz_driver *driver) static void openvzDriverLock(struct openvz_driver *driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void openvzDriverUnlock(struct openvz_driver *driver) static void openvzDriverUnlock(struct openvz_driver *driver)
{ {
pthread_mutex_unlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
struct openvz_driver ovz_driver; struct openvz_driver ovz_driver;

View File

@ -32,6 +32,7 @@
#include "network_conf.h" #include "network_conf.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "domain_event.h" #include "domain_event.h"
#include "threads.h"
#define qemudDebug(fmt, ...) do {} while(0) #define qemudDebug(fmt, ...) do {} while(0)
@ -51,7 +52,7 @@ enum qemud_cmd_flags {
/* Main driver state */ /* Main driver state */
struct qemud_driver { struct qemud_driver {
PTHREAD_MUTEX_T(lock); virMutex lock;
unsigned int qemuVersion; unsigned int qemuVersion;
int nextvmid; int nextvmid;

View File

@ -78,11 +78,11 @@ static int qemudShutdown(void);
static void qemuDriverLock(struct qemud_driver *driver) static void qemuDriverLock(struct qemud_driver *driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void qemuDriverUnlock(struct qemud_driver *driver) static void qemuDriverUnlock(struct qemud_driver *driver)
{ {
pthread_mutex_unlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
static int qemudSetCloseExec(int fd) { static int qemudSetCloseExec(int fd) {
@ -273,7 +273,11 @@ qemudStartup(void) {
if (VIR_ALLOC(qemu_driver) < 0) if (VIR_ALLOC(qemu_driver) < 0)
return -1; 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); qemuDriverLock(qemu_driver);
/* Don't have a dom0 so start from 1 */ /* Don't have a dom0 so start from 1 */
@ -482,6 +486,7 @@ qemudShutdown(void) {
brShutdown(qemu_driver->brctl); brShutdown(qemu_driver->brctl);
qemuDriverUnlock(qemu_driver); qemuDriverUnlock(qemu_driver);
virMutexDestroy(&qemu_driver->lock);
VIR_FREE(qemu_driver); VIR_FREE(qemu_driver);
return 0; return 0;

View File

@ -297,6 +297,9 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj) {
VIR_FREE(obj->configFile); VIR_FREE(obj->configFile);
VIR_FREE(obj->autostartLink); VIR_FREE(obj->autostartLink);
virMutexDestroy(&obj->lock);
VIR_FREE(obj); VIR_FREE(obj);
} }
@ -1259,13 +1262,19 @@ virStoragePoolObjAssignDef(virConnectPtr conn,
return NULL; 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); virStoragePoolObjLock(pool);
pool->active = 0; pool->active = 0;
pool->def = def; pool->def = def;
if (VIR_REALLOC_N(pools->objs, pools->count+1) < 0) { if (VIR_REALLOC_N(pools->objs, pools->count+1) < 0) {
pool->def = NULL; pool->def = NULL;
virStoragePoolObjUnlock(pool);
virStoragePoolObjFree(pool); virStoragePoolObjFree(pool);
virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL); virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL);
return NULL; return NULL;
@ -1530,23 +1539,12 @@ char *virStoragePoolSourceListFormat(virConnectPtr conn,
} }
#ifdef HAVE_PTHREAD_H
void virStoragePoolObjLock(virStoragePoolObjPtr obj) void virStoragePoolObjLock(virStoragePoolObjPtr obj)
{ {
pthread_mutex_lock(&obj->lock); virMutexLock(&obj->lock);
} }
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj) 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

View File

@ -26,6 +26,7 @@
#include "internal.h" #include "internal.h"
#include "util.h" #include "util.h"
#include "threads.h"
/* Shared structs */ /* Shared structs */
@ -223,7 +224,7 @@ typedef struct _virStoragePoolObj virStoragePoolObj;
typedef virStoragePoolObj *virStoragePoolObjPtr; typedef virStoragePoolObj *virStoragePoolObjPtr;
struct _virStoragePoolObj { struct _virStoragePoolObj {
PTHREAD_MUTEX_T(lock); virMutex lock;
char *configFile; char *configFile;
char *autostartLink; char *autostartLink;
@ -250,7 +251,7 @@ typedef struct _virStorageDriverState virStorageDriverState;
typedef virStorageDriverState *virStorageDriverStatePtr; typedef virStorageDriverState *virStorageDriverStatePtr;
struct _virStorageDriverState { struct _virStorageDriverState {
PTHREAD_MUTEX_T(lock); virMutex lock;
virStoragePoolObjList pools; virStoragePoolObjList pools;

View File

@ -49,11 +49,11 @@ static int storageDriverShutdown(void);
static void storageDriverLock(virStorageDriverStatePtr driver) static void storageDriverLock(virStorageDriverStatePtr driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void storageDriverUnlock(virStorageDriverStatePtr driver) static void storageDriverUnlock(virStorageDriverStatePtr driver)
{ {
pthread_mutex_unlock(&driver->lock); virMutexUnlock(&driver->lock);
} }
static void static void
@ -113,7 +113,10 @@ storageDriverStartup(void) {
if (VIR_ALLOC(driverState) < 0) if (VIR_ALLOC(driverState) < 0)
return -1; return -1;
pthread_mutex_init(&driverState->lock, NULL); if (virMutexInit(&driverState->lock) < 0) {
VIR_FREE(driverState);
return -1;
}
storageDriverLock(driverState); storageDriverLock(driverState);
if (!uid) { if (!uid) {
@ -266,6 +269,7 @@ storageDriverShutdown(void) {
VIR_FREE(driverState->configDir); VIR_FREE(driverState->configDir);
VIR_FREE(driverState->autostartDir); VIR_FREE(driverState->autostartDir);
storageDriverUnlock(driverState); storageDriverUnlock(driverState);
virMutexDestroy(&driverState->lock);
VIR_FREE(driverState); VIR_FREE(driverState);
return 0; return 0;

View File

@ -44,6 +44,7 @@
#include "domain_conf.h" #include "domain_conf.h"
#include "storage_conf.h" #include "storage_conf.h"
#include "xml.h" #include "xml.h"
#include "threads.h"
#define MAX_CPUS 128 #define MAX_CPUS 128
@ -58,7 +59,7 @@ typedef struct _testCell *testCellPtr;
#define MAX_CELLS 128 #define MAX_CELLS 128
struct _testConn { struct _testConn {
PTHREAD_MUTEX_T(lock); virMutex lock;
char path[PATH_MAX]; char path[PATH_MAX];
int nextDomID; int nextDomID;
@ -93,20 +94,15 @@ static const virNodeInfo defaultNodeInfo = {
virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \ virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \
__FUNCTION__, __LINE__, fmt) __FUNCTION__, __LINE__, fmt)
#ifdef HAVE_THREAD_H
static void testDriverLock(testConnPtr driver) static void testDriverLock(testConnPtr driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void testDriverUnlock(testConnPtr driver) 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 static virCapsPtr
testBuildCapabilities(virConnectPtr conn) { testBuildCapabilities(virConnectPtr conn) {
@ -216,9 +212,15 @@ static int testOpenDefault(virConnectPtr conn) {
testError(conn, VIR_ERR_NO_MEMORY, "testConn"); testError(conn, VIR_ERR_NO_MEMORY, "testConn");
return VIR_DRV_OPEN_ERROR; return VIR_DRV_OPEN_ERROR;
} }
conn->privateData = privconn; if (virMutexInit(&privconn->lock) < 0) {
pthread_mutex_init(&privconn->lock, NULL); testError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot initialize mutex"));
VIR_FREE(privconn);
return VIR_DRV_OPEN_ERROR;
}
testDriverLock(privconn); testDriverLock(privconn);
conn->privateData = privconn;
if (gettimeofday(&tv, NULL) < 0) { if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("getting time of day")); testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("getting time of day"));
@ -282,6 +284,7 @@ static int testOpenDefault(virConnectPtr conn) {
virStoragePoolObjUnlock(poolobj); virStoragePoolObjUnlock(poolobj);
testDriverUnlock(privconn); testDriverUnlock(privconn);
return VIR_DRV_OPEN_SUCCESS; return VIR_DRV_OPEN_SUCCESS;
error: error:
@ -290,6 +293,7 @@ error:
virStoragePoolObjListFree(&privconn->pools); virStoragePoolObjListFree(&privconn->pools);
virCapabilitiesFree(privconn->caps); virCapabilitiesFree(privconn->caps);
testDriverUnlock(privconn); testDriverUnlock(privconn);
conn->privateData = NULL;
VIR_FREE(privconn); VIR_FREE(privconn);
return VIR_DRV_OPEN_ERROR; return VIR_DRV_OPEN_ERROR;
} }
@ -335,9 +339,15 @@ static int testOpenFromFile(virConnectPtr conn,
testError(NULL, VIR_ERR_NO_MEMORY, "testConn"); testError(NULL, VIR_ERR_NO_MEMORY, "testConn");
return VIR_DRV_OPEN_ERROR; return VIR_DRV_OPEN_ERROR;
} }
conn->privateData = privconn; if (virMutexInit(&privconn->lock) < 0) {
pthread_mutex_init(&privconn->lock, NULL); testError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot initialize mutex"));
VIR_FREE(privconn);
return VIR_DRV_OPEN_ERROR;
}
testDriverLock(privconn); testDriverLock(privconn);
conn->privateData = privconn;
if (!(privconn->caps = testBuildCapabilities(conn))) if (!(privconn->caps = testBuildCapabilities(conn)))
goto error; goto error;
@ -643,6 +653,7 @@ static int testClose(virConnectPtr conn)
virNetworkObjListFree(&privconn->networks); virNetworkObjListFree(&privconn->networks);
virStoragePoolObjListFree(&privconn->pools); virStoragePoolObjListFree(&privconn->pools);
testDriverUnlock(privconn); testDriverUnlock(privconn);
virMutexDestroy(&privconn->lock);
VIR_FREE (privconn); VIR_FREE (privconn);
conn->privateData = NULL; conn->privateData = NULL;

117
src/threads-pthread.c Normal file
View File

@ -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);
}

36
src/threads-pthread.h Normal file
View File

@ -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;
};

223
src/threads-win32.c Normal file
View File

@ -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);
}

39
src/threads-win32.h Normal file
View File

@ -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;
};

34
src/threads.c Normal file
View File

@ -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

72
src/threads.h Normal file
View File

@ -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

View File

@ -30,6 +30,7 @@
#include "network_conf.h" #include "network_conf.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "virterror_internal.h" #include "virterror_internal.h"
#include "threads.h"
#define umlDebug(fmt, ...) do {} while(0) #define umlDebug(fmt, ...) do {} while(0)
@ -39,7 +40,7 @@
/* Main driver state */ /* Main driver state */
struct uml_driver { struct uml_driver {
PTHREAD_MUTEX_T(lock); virMutex lock;
unsigned int umlVersion; unsigned int umlVersion;
int nextvmid; int nextvmid;

View File

@ -74,11 +74,11 @@ static int umlShutdown(void);
static void umlDriverLock(struct uml_driver *driver) static void umlDriverLock(struct uml_driver *driver)
{ {
pthread_mutex_lock(&driver->lock); virMutexLock(&driver->lock);
} }
static void umlDriverUnlock(struct uml_driver *driver) 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) if (VIR_ALLOC(uml_driver) < 0)
return -1; return -1;
pthread_mutex_init(&uml_driver->lock, NULL); if (virMutexInit(&uml_driver->lock) < 0) {
VIR_FREE(uml_driver);
return -1;
}
umlDriverLock(uml_driver); umlDriverLock(uml_driver);
/* Don't have a dom0 so start from 1 */ /* Don't have a dom0 so start from 1 */
@ -501,6 +504,7 @@ umlShutdown(void) {
brShutdown(uml_driver->brctl); brShutdown(uml_driver->brctl);
umlDriverUnlock(uml_driver); umlDriverUnlock(uml_driver);
virMutexDestroy(&uml_driver->lock);
VIR_FREE(uml_driver); VIR_FREE(uml_driver);
return 0; return 0;