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>
* src/util.c: Implement virKill() for Win32 platform

View File

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

View File

@ -12,6 +12,7 @@ libexec_PROGRAMS = libvirt_proxy
libvirt_proxy_SOURCES = libvirt_proxy.c @top_srcdir@/src/xend_internal.c \
@top_srcdir@/src/xen_internal.c @top_srcdir@/src/virterror.c \
@top_srcdir@/src/sexpr.c \
@top_srcdir@/src/threads.c \
@top_srcdir@/src/xs_internal.c @top_srcdir@/src/buf.c \
@top_srcdir@/src/capabilities.c \
@top_srcdir@/src/memory.c \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -433,6 +433,8 @@ void virDomainObjFree(virDomainObjPtr dom)
VIR_FREE(dom->monitorpath);
VIR_FREE(dom->vcpupids);
virMutexDestroy(&dom->lock);
VIR_FREE(dom);
}
@ -471,7 +473,13 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
return NULL;
}
pthread_mutex_init(&domain->lock, NULL);
if (virMutexInit(&domain->lock) < 0) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot initialize mutex"));
VIR_FREE(domain);
return NULL;
}
virDomainObjLock(domain);
domain->state = VIR_DOMAIN_SHUTOFF;
domain->def = def;
@ -3660,26 +3668,14 @@ const char *virDomainDefDefaultEmulator(virConnectPtr conn,
}
#ifdef HAVE_PTHREAD_H
void virDomainObjLock(virDomainObjPtr obj)
{
pthread_mutex_lock(&obj->lock);
virMutexLock(&obj->lock);
}
void virDomainObjUnlock(virDomainObjPtr obj)
{
pthread_mutex_unlock(&obj->lock);
virMutexUnlock(&obj->lock);
}
#else
void virDomainObjLock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
{
}
void virDomainObjUnlock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
{
}
#endif
#endif /* ! PROXY */

View File

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

View File

@ -13,19 +13,6 @@
#include <sys/syslimits.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#define PTHREAD_MUTEX_T(v) pthread_mutex_t v
#else
/* Mutex functions disappear if we don't have pthread. */
#define PTHREAD_MUTEX_T(v) /*empty*/
#define pthread_mutex_init(lk,p) /*empty*/
#define pthread_mutex_destroy(lk) /*empty*/
#define pthread_mutex_lock(lk) /*empty*/
#define pthread_mutex_unlock(lk) /*empty*/
#define pthread_sigmask(h, s, o) sigprocmask((h), (s), (o))
#endif
/* The library itself is allowed to use deprecated functions /
* variables, so effectively undefine the deprecated attribute
* which would otherwise be defined in libvirt.h.

View File

@ -253,8 +253,12 @@ virInitialize(void)
#endif
if (initialized)
return(0);
initialized = 1;
if (virThreadInitialize() < 0)
return -1;
#ifdef ENABLE_DEBUG
debugEnv = getenv("LIBVIRT_DEBUG");
if (debugEnv && *debugEnv && *debugEnv != '0') {
@ -316,6 +320,43 @@ virInitialize(void)
return(0);
}
#ifdef WIN32
BOOL WINAPI
DllMain (HINSTANCE instance, DWORD reason, LPVOID ignore);
BOOL WINAPI
DllMain (HINSTANCE instance ATTRIBUTE_UNUSED,
DWORD reason,
LPVOID ignore ATTRIBUTE_UNUSED)
{
switch (reason) {
case DLL_PROCESS_ATTACH:
fprintf(stderr, "Initializing DLL\n");
virInitialize();
break;
case DLL_THREAD_ATTACH:
fprintf(stderr, "Thread start\n");
/* Nothing todo in libvirt yet */
break;
case DLL_THREAD_DETACH:
fprintf(stderr, "Thread exit\n");
/* Release per-thread local data */
virThreadOnExit();
break;
case DLL_PROCESS_DETACH:
fprintf(stderr, "Process exit\n");
/* Don't bother releasing per-thread data
since (hopefully) windows cleans up
everything on process exit */
break;
}
return TRUE;
}
#endif
/**

View File

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

View File

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

View File

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

View File

@ -57,11 +57,11 @@ static lxc_driver_t *lxc_driver = NULL;
static void lxcDriverLock(lxc_driver_t *driver)
{
pthread_mutex_lock(&driver->lock);
virMutexLock(&driver->lock);
}
static void lxcDriverUnlock(lxc_driver_t *driver)
{
pthread_mutex_unlock(&driver->lock);
virMutexUnlock(&driver->lock);
}
@ -1135,7 +1135,10 @@ static int lxcStartup(void)
if (VIR_ALLOC(lxc_driver) < 0) {
return -1;
}
pthread_mutex_init(&lxc_driver->lock, NULL);
if (virMutexInit(&lxc_driver->lock) < 0) {
VIR_FREE(lxc_driver);
return -1;
}
lxcDriverLock(lxc_driver);
/* Check that this is a container enabled kernel */
@ -1228,6 +1231,7 @@ static int lxcShutdown(void)
VIR_FREE(lxc_driver->stateDir);
VIR_FREE(lxc_driver->logDir);
lxcDriverUnlock(lxc_driver);
virMutexDestroy(&lxc_driver->lock);
VIR_FREE(lxc_driver);
lxc_driver = NULL;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -392,11 +392,18 @@ int openvzLoadDomains(struct openvz_driver *driver) {
goto cleanup;
}
if (VIR_ALLOC(dom) < 0 ||
VIR_ALLOC(dom->def) < 0)
if (VIR_ALLOC(dom) < 0)
goto no_memory;
pthread_mutex_init(&dom->lock, NULL);
if (virMutexInit(&dom->lock) < 0) {
openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot initialize mutex"));
VIR_FREE(dom);
goto cleanup;
}
if (VIR_ALLOC(dom->def) < 0)
goto no_memory;
if (STREQ(status, "stopped"))
dom->state = VIR_DOMAIN_SHUTOFF;

View File

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

View File

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

View File

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

View File

@ -78,11 +78,11 @@ static int qemudShutdown(void);
static void qemuDriverLock(struct qemud_driver *driver)
{
pthread_mutex_lock(&driver->lock);
virMutexLock(&driver->lock);
}
static void qemuDriverUnlock(struct qemud_driver *driver)
{
pthread_mutex_unlock(&driver->lock);
virMutexUnlock(&driver->lock);
}
static int qemudSetCloseExec(int fd) {
@ -273,7 +273,11 @@ qemudStartup(void) {
if (VIR_ALLOC(qemu_driver) < 0)
return -1;
pthread_mutex_init(&qemu_driver->lock, NULL);
if (virMutexInit(&qemu_driver->lock) < 0) {
qemudLog(QEMUD_ERROR, "%s", _("cannot initialize mutex"));
VIR_FREE(qemu_driver);
return -1;
}
qemuDriverLock(qemu_driver);
/* Don't have a dom0 so start from 1 */
@ -482,6 +486,7 @@ qemudShutdown(void) {
brShutdown(qemu_driver->brctl);
qemuDriverUnlock(qemu_driver);
virMutexDestroy(&qemu_driver->lock);
VIR_FREE(qemu_driver);
return 0;

View File

@ -297,6 +297,9 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj) {
VIR_FREE(obj->configFile);
VIR_FREE(obj->autostartLink);
virMutexDestroy(&obj->lock);
VIR_FREE(obj);
}
@ -1259,13 +1262,19 @@ virStoragePoolObjAssignDef(virConnectPtr conn,
return NULL;
}
pthread_mutex_init(&pool->lock, NULL);
if (virMutexInit(&pool->lock) < 0) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot initialize mutex"));
VIR_FREE(pool);
return NULL;
}
virStoragePoolObjLock(pool);
pool->active = 0;
pool->def = def;
if (VIR_REALLOC_N(pools->objs, pools->count+1) < 0) {
pool->def = NULL;
virStoragePoolObjUnlock(pool);
virStoragePoolObjFree(pool);
virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL);
return NULL;
@ -1530,23 +1539,12 @@ char *virStoragePoolSourceListFormat(virConnectPtr conn,
}
#ifdef HAVE_PTHREAD_H
void virStoragePoolObjLock(virStoragePoolObjPtr obj)
{
pthread_mutex_lock(&obj->lock);
virMutexLock(&obj->lock);
}
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj)
{
pthread_mutex_unlock(&obj->lock);
virMutexUnlock(&obj->lock);
}
#else
void virStoragePoolObjLock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
{
}
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
{
}
#endif

View File

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

View File

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

View File

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

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 "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;

View File

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