From 746f4373e7234a5eee64de646ae21a461ad9da99 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 4 Dec 2008 22:00:14 +0000 Subject: [PATCH] Impl of threading locking APIs --- ChangeLog | 10 +++++++++ src/domain_conf.c | 40 ++++++++++++++++++++++++++++++++---- src/domain_conf.h | 2 ++ src/network_conf.c | 46 ++++++++++++++++++++++++++++++++++-------- src/network_conf.h | 2 ++ src/node_device_conf.c | 28 ++++++++++++++++++++++++- src/node_device_conf.h | 2 ++ src/storage_conf.c | 35 +++++++++++++++++++++++++++++--- src/storage_conf.h | 2 ++ 9 files changed, 151 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3ddb69e92..fd2d3f6c62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Dec 4 21:49:41 GMT 2008 Daniel P. Berrange + + Per object locking implementation + * src/domain_conf.c, src/domain_conf.h, src/network_conf.c, + src/network_conf.h, src/node_device_conf.c, + src/node_device_conf.h, src/storage_conf.c + src/storage_conf.h: Add implementation of locking APIs, + and make object lookup / creation methods return locked + objects + Thu Dec 4 21:48:41 GMT 2008 Daniel P. Berrange * src/libvirt_sym.version.in, src/node_device.c, diff --git a/src/domain_conf.c b/src/domain_conf.c index 2740ab72e8..ad82a16e7a 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -151,10 +151,13 @@ virDomainObjPtr virDomainFindByID(const virDomainObjListPtr doms, { unsigned int i; - for (i = 0 ; i < doms->count ; i++) + for (i = 0 ; i < doms->count ; i++) { + virDomainObjLock(doms->objs[i]); if (virDomainIsActive(doms->objs[i]) && doms->objs[i]->def->id == id) return doms->objs[i]; + virDomainObjUnlock(doms->objs[i]); + } return NULL; } @@ -165,9 +168,12 @@ virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms, { unsigned int i; - for (i = 0 ; i < doms->count ; i++) + for (i = 0 ; i < doms->count ; i++) { + virDomainObjLock(doms->objs[i]); if (!memcmp(doms->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) return doms->objs[i]; + virDomainObjUnlock(doms->objs[i]); + } return NULL; } @@ -177,9 +183,12 @@ virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms, { unsigned int i; - for (i = 0 ; i < doms->count ; i++) + for (i = 0 ; i < doms->count ; i++) { + virDomainObjLock(doms->objs[i]); if (STREQ(doms->objs[i]->def->name, name)) return doms->objs[i]; + virDomainObjUnlock(doms->objs[i]); + } return NULL; } @@ -455,6 +464,8 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn, return NULL; } + pthread_mutex_init(&domain->lock, NULL); + virDomainObjLock(domain); domain->state = VIR_DOMAIN_SHUTOFF; domain->def = def; @@ -475,8 +486,12 @@ void virDomainRemoveInactive(virDomainObjListPtr doms, { unsigned int i; + virDomainObjUnlock(dom); + for (i = 0 ; i < doms->count ; i++) { + virDomainObjLock(doms->objs[i]); if (doms->objs[i] == dom) { + virDomainObjUnlock(doms->objs[i]); virDomainObjFree(doms->objs[i]); if (i < (doms->count - 1)) @@ -490,6 +505,7 @@ void virDomainRemoveInactive(virDomainObjListPtr doms, break; } + virDomainObjUnlock(doms->objs[i]); } } @@ -3348,8 +3364,10 @@ int virDomainLoadAllConfigs(virConnectPtr conn, entry->d_name, notify, opaque); - if (dom) + if (dom) { + virDomainObjUnlock(dom); dom->persistent = 1; + } } closedir(dir); @@ -3470,6 +3488,19 @@ const char *virDomainDefDefaultEmulator(virConnectPtr conn, } +#ifdef HAVE_PTHREAD_H + +void virDomainObjLock(virDomainObjPtr obj) +{ + pthread_mutex_lock(&obj->lock); +} + +void virDomainObjUnlock(virDomainObjPtr obj) +{ + pthread_mutex_unlock(&obj->lock); +} + +#else void virDomainObjLock(virDomainObjPtr obj ATTRIBUTE_UNUSED) { } @@ -3477,5 +3508,6 @@ void virDomainObjLock(virDomainObjPtr obj ATTRIBUTE_UNUSED) void virDomainObjUnlock(virDomainObjPtr obj ATTRIBUTE_UNUSED) { } +#endif #endif /* ! PROXY */ diff --git a/src/domain_conf.h b/src/domain_conf.h index 7640557852..51cf6d56d5 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -454,6 +454,8 @@ struct _virDomainDef { typedef struct _virDomainObj virDomainObj; typedef virDomainObj *virDomainObjPtr; struct _virDomainObj { + PTHREAD_MUTEX_T(lock); + int stdin_fd; int stdout_fd; int stdout_watch; diff --git a/src/network_conf.c b/src/network_conf.c index 0dfde672db..21dbc674cf 100644 --- a/src/network_conf.c +++ b/src/network_conf.c @@ -58,9 +58,12 @@ virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjListPtr nets, { unsigned int i; - for (i = 0 ; i < nets->count ; i++) + for (i = 0 ; i < nets->count ; i++) { + virNetworkObjLock(nets->objs[i]); if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) return nets->objs[i]; + virNetworkObjUnlock(nets->objs[i]); + } return NULL; } @@ -70,9 +73,12 @@ virNetworkObjPtr virNetworkFindByName(const virNetworkObjListPtr nets, { unsigned int i; - for (i = 0 ; i < nets->count ; i++) + for (i = 0 ; i < nets->count ; i++) { + virNetworkObjLock(nets->objs[i]); if (STREQ(nets->objs[i]->def->name, name)) return nets->objs[i]; + virNetworkObjUnlock(nets->objs[i]); + } return NULL; } @@ -157,7 +163,8 @@ virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn, virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); return NULL; } - + pthread_mutex_init(&network->lock, NULL); + virNetworkObjLock(network); network->def = def; if (VIR_REALLOC_N(nets->objs, nets->count + 1) < 0) { @@ -178,8 +185,11 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets, { unsigned int i; + virNetworkObjUnlock(net); for (i = 0 ; i < nets->count ; i++) { + virNetworkObjLock(nets->objs[i]); if (nets->objs[i] == net) { + virNetworkObjUnlock(nets->objs[i]); virNetworkObjFree(nets->objs[i]); if (i < (nets->count - 1)) @@ -193,6 +203,7 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets, break; } + virNetworkObjUnlock(nets->objs[i]); } } @@ -770,6 +781,8 @@ int virNetworkLoadAllConfigs(virConnectPtr conn, } while ((entry = readdir(dir))) { + virNetworkObjPtr net; + if (entry->d_name[0] == '.') continue; @@ -778,11 +791,13 @@ int virNetworkLoadAllConfigs(virConnectPtr conn, /* NB: ignoring errors, so one malformed config doesn't kill the whole process */ - virNetworkLoadConfig(conn, - nets, - configDir, - autostartDir, - entry->d_name); + net = virNetworkLoadConfig(conn, + nets, + configDir, + autostartDir, + entry->d_name); + if (net) + virNetworkObjUnlock(net); } closedir(dir); @@ -812,6 +827,19 @@ int virNetworkDeleteConfig(virConnectPtr conn, return 0; } +#ifdef HAVE_PTHREAD_H + +void virNetworkObjLock(virNetworkObjPtr obj) +{ + pthread_mutex_lock(&obj->lock); +} + +void virNetworkObjUnlock(virNetworkObjPtr obj) +{ + pthread_mutex_unlock(&obj->lock); +} + +#else void virNetworkObjLock(virNetworkObjPtr obj ATTRIBUTE_UNUSED) { } @@ -819,3 +847,5 @@ void virNetworkObjLock(virNetworkObjPtr obj ATTRIBUTE_UNUSED) void virNetworkObjUnlock(virNetworkObjPtr obj ATTRIBUTE_UNUSED) { } + +#endif diff --git a/src/network_conf.h b/src/network_conf.h index c83eeabc97..47bfc6e307 100644 --- a/src/network_conf.h +++ b/src/network_conf.h @@ -82,6 +82,8 @@ struct _virNetworkDef { typedef struct _virNetworkObj virNetworkObj; typedef virNetworkObj *virNetworkObjPtr; struct _virNetworkObj { + PTHREAD_MUTEX_T(lock); + pid_t dnsmasqPid; unsigned int active : 1; unsigned int autostart : 1; diff --git a/src/node_device_conf.c b/src/node_device_conf.c index bee466b119..526cd84588 100644 --- a/src/node_device_conf.c +++ b/src/node_device_conf.c @@ -59,9 +59,12 @@ virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs, { unsigned int i; - for (i = 0; i < devs->count; i++) + for (i = 0; i < devs->count; i++) { + virNodeDeviceObjLock(devs->objs[i]); if (STREQ(devs->objs[i]->def->name, name)) return devs->objs[i]; + virNodeDeviceObjUnlock(devs->objs[i]); + } return NULL; } @@ -125,6 +128,8 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn, return NULL; } + pthread_mutex_init(&device->lock, NULL); + virNodeDeviceObjLock(device); device->def = def; if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) { @@ -144,8 +149,12 @@ void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, { unsigned int i; + virNodeDeviceObjUnlock(dev); + for (i = 0; i < devs->count; i++) { + virNodeDeviceObjLock(dev); if (devs->objs[i] == dev) { + virNodeDeviceObjUnlock(dev); virNodeDeviceObjFree(devs->objs[i]); if (i < (devs->count - 1)) @@ -159,6 +168,7 @@ void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, break; } + virNodeDeviceObjUnlock(dev); } } @@ -398,6 +408,20 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) } +#ifdef HAVE_PTHREAD_H + +void virNodeDeviceObjLock(virNodeDeviceObjPtr obj) +{ + pthread_mutex_lock(&obj->lock); +} + +void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj) +{ + pthread_mutex_unlock(&obj->lock); +} + +#else + void virNodeDeviceObjLock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED) { } @@ -405,3 +429,5 @@ void virNodeDeviceObjLock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED) void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED) { } + +#endif diff --git a/src/node_device_conf.h b/src/node_device_conf.h index 6f03a012cf..5addbab1ac 100644 --- a/src/node_device_conf.h +++ b/src/node_device_conf.h @@ -142,6 +142,8 @@ struct _virNodeDeviceDef { typedef struct _virNodeDeviceObj virNodeDeviceObj; typedef virNodeDeviceObj *virNodeDeviceObjPtr; struct _virNodeDeviceObj { + PTHREAD_MUTEX_T(lock); + virNodeDeviceDefPtr def; /* device definition */ void *privateData; /* driver-specific private data */ void (*privateFree)(void *data); /* destructor for private data */ diff --git a/src/storage_conf.c b/src/storage_conf.c index c54490a99d..522fc984ba 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -310,8 +310,12 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, { unsigned int i; + virStoragePoolObjUnlock(pool); + for (i = 0 ; i < pools->count ; i++) { + virStoragePoolObjLock(pools->objs[i]); if (pools->objs[i] == pool) { + virStoragePoolObjUnlock(pools->objs[i]); virStoragePoolObjFree(pools->objs[i]); if (i < (pools->count - 1)) @@ -325,6 +329,7 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, break; } + virStoragePoolObjUnlock(pools->objs[i]); } } @@ -1153,9 +1158,12 @@ virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, const unsigned char *uuid) { unsigned int i; - for (i = 0 ; i < pools->count ; i++) + for (i = 0 ; i < pools->count ; i++) { + virStoragePoolObjLock(pools->objs[i]); if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) return pools->objs[i]; + virStoragePoolObjUnlock(pools->objs[i]); + } return NULL; } @@ -1165,9 +1173,12 @@ virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, const char *name) { unsigned int i; - for (i = 0 ; i < pools->count ; i++) + for (i = 0 ; i < pools->count ; i++) { + virStoragePoolObjLock(pools->objs[i]); if (STREQ(pools->objs[i]->def->name, name)) return pools->objs[i]; + virStoragePoolObjUnlock(pools->objs[i]); + } return NULL; } @@ -1243,6 +1254,8 @@ virStoragePoolObjAssignDef(virConnectPtr conn, return NULL; } + pthread_mutex_init(&pool->lock, NULL); + virStoragePoolObjLock(pool); pool->active = 0; pool->def = def; @@ -1327,6 +1340,7 @@ virStoragePoolLoadAllConfigs(virConnectPtr conn, char *xml = NULL; char path[PATH_MAX]; char autostartLink[PATH_MAX]; + virStoragePoolObjPtr pool; if (entry->d_name[0] == '.') continue; @@ -1351,7 +1365,9 @@ virStoragePoolLoadAllConfigs(virConnectPtr conn, if (virFileReadAll(path, 8192, &xml) < 0) continue; - virStoragePoolObjLoad(conn, pools, entry->d_name, path, xml, autostartLink); + pool = virStoragePoolObjLoad(conn, pools, entry->d_name, path, xml, autostartLink); + if (pool) + virStoragePoolObjUnlock(pool); VIR_FREE(xml); } @@ -1509,6 +1525,18 @@ char *virStoragePoolSourceListFormat(virConnectPtr conn, } +#ifdef HAVE_PTHREAD_H + +void virStoragePoolObjLock(virStoragePoolObjPtr obj) +{ + pthread_mutex_lock(&obj->lock); +} + +void virStoragePoolObjUnlock(virStoragePoolObjPtr obj) +{ + pthread_mutex_unlock(&obj->lock); +} +#else void virStoragePoolObjLock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED) { } @@ -1516,3 +1544,4 @@ void virStoragePoolObjLock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED) void virStoragePoolObjUnlock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED) { } +#endif diff --git a/src/storage_conf.h b/src/storage_conf.h index 6ee3f9d030..76ea9135b0 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -223,6 +223,8 @@ typedef struct _virStoragePoolObj virStoragePoolObj; typedef virStoragePoolObj *virStoragePoolObjPtr; struct _virStoragePoolObj { + PTHREAD_MUTEX_T(lock); + char *configFile; char *autostartLink; int active;