+Thu Dec 4 21:49:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
+
+ 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 <berrange@redhat.com>
* src/libvirt_sym.version.in, src/node_device.c,
{
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;
}
{
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;
}
{
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;
}
return NULL;
}
+ pthread_mutex_init(&domain->lock, NULL);
+ virDomainObjLock(domain);
domain->state = VIR_DOMAIN_SHUTOFF;
domain->def = def;
{
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))
break;
}
+ virDomainObjUnlock(doms->objs[i]);
}
}
entry->d_name,
notify,
opaque);
- if (dom)
+ if (dom) {
+ virDomainObjUnlock(dom);
dom->persistent = 1;
+ }
}
closedir(dir);
}
+#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)
{
}
void virDomainObjUnlock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
{
}
+#endif
#endif /* ! PROXY */
typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj {
+ PTHREAD_MUTEX_T(lock);
+
int stdin_fd;
int stdout_fd;
int stdout_watch;
{
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;
}
{
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;
}
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) {
{
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))
break;
}
+ virNetworkObjUnlock(nets->objs[i]);
}
}
}
while ((entry = readdir(dir))) {
+ virNetworkObjPtr net;
+
if (entry->d_name[0] == '.')
continue;
/* 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);
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)
{
}
void virNetworkObjUnlock(virNetworkObjPtr obj ATTRIBUTE_UNUSED)
{
}
+
+#endif
typedef struct _virNetworkObj virNetworkObj;
typedef virNetworkObj *virNetworkObjPtr;
struct _virNetworkObj {
+ PTHREAD_MUTEX_T(lock);
+
pid_t dnsmasqPid;
unsigned int active : 1;
unsigned int autostart : 1;
{
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;
}
return NULL;
}
+ pthread_mutex_init(&device->lock, NULL);
+ virNodeDeviceObjLock(device);
device->def = def;
if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) {
{
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))
break;
}
+ virNodeDeviceObjUnlock(dev);
}
}
}
+#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)
{
}
void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED)
{
}
+
+#endif
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 */
{
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))
break;
}
+ virStoragePoolObjUnlock(pools->objs[i]);
}
}
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;
}
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;
}
return NULL;
}
+ pthread_mutex_init(&pool->lock, NULL);
+ virStoragePoolObjLock(pool);
pool->active = 0;
pool->def = def;
char *xml = NULL;
char path[PATH_MAX];
char autostartLink[PATH_MAX];
+ virStoragePoolObjPtr pool;
if (entry->d_name[0] == '.')
continue;
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);
}
}
+#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)
{
}
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
{
}
+#endif
typedef virStoragePoolObj *virStoragePoolObjPtr;
struct _virStoragePoolObj {
+ PTHREAD_MUTEX_T(lock);
+
char *configFile;
char *autostartLink;
int active;