1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

Add reference counting on virDomainObjPtr objects

Add reference counting on the virDomainObjPtr objects. With the
forthcoming asynchronous QEMU monitor, it will be neccessary to
release the lock on virDomainObjPtr while waiting for a monitor
command response. It is neccessary to ensure one thread can't
delete a virDomainObjPtr while another is waiting. By introducing
reference counting threads can make sure objects they are using
are not accidentally deleted while unlocked.

* src/conf/domain_conf.h, src/conf/domain_conf.c: Add
  virDomainObjRef/Unref APIs, remove virDomainObjFree
* src/openvz/openvz_conf.c: replace call to virDomainObjFree
  with virDomainObjUnref
This commit is contained in:
Daniel P. Berrange 2009-10-15 12:30:26 +01:00
parent 77cfcccfa8
commit a340f9131a
4 changed files with 39 additions and 7 deletions

View File

@ -228,7 +228,9 @@ int virDomainObjListInit(virDomainObjListPtr doms)
static void virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
{
virDomainObjPtr obj = payload;
virDomainObjFree(obj);
virDomainObjLock(obj);
if (!virDomainObjUnref(obj))
virDomainObjUnlock(obj);
}
void virDomainObjListDeinit(virDomainObjListPtr doms)
@ -602,11 +604,12 @@ void virDomainDefFree(virDomainDefPtr def)
#ifndef PROXY
void virDomainObjFree(virDomainObjPtr dom)
static void virDomainObjFree(virDomainObjPtr dom)
{
if (!dom)
return;
VIR_DEBUG("obj=%p", dom);
virDomainDefFree(dom->def);
virDomainDefFree(dom->newDef);
@ -622,6 +625,25 @@ void virDomainObjFree(virDomainObjPtr dom)
VIR_FREE(dom);
}
void virDomainObjRef(virDomainObjPtr dom)
{
dom->refs++;
VIR_DEBUG("obj=%p refs=%d", dom, dom->refs);
}
int virDomainObjUnref(virDomainObjPtr dom)
{
dom->refs--;
VIR_DEBUG("obj=%p refs=%d", dom, dom->refs);
if (dom->refs == 0) {
virDomainObjUnlock(dom);
virDomainObjFree(dom);
return 1;
}
return 0;
}
static virDomainObjPtr virDomainObjNew(virConnectPtr conn,
virCapsPtr caps)
{
@ -653,7 +675,9 @@ static virDomainObjPtr virDomainObjNew(virConnectPtr conn,
domain->state = VIR_DOMAIN_SHUTOFF;
domain->monitorWatch = -1;
domain->monitor = -1;
domain->refs = 1;
VIR_DEBUG("obj=%p", domain);
return domain;
}
@ -3455,7 +3479,7 @@ static virDomainObjPtr virDomainObjParseXML(virConnectPtr conn,
error:
VIR_FREE(nodes);
virDomainChrDefFree(obj->monitor_chr);
virDomainObjFree(obj);
virDomainObjUnref(obj);
return NULL;
}
@ -5052,7 +5076,7 @@ static virDomainObjPtr virDomainLoadStatus(virConnectPtr conn,
return obj;
error:
virDomainObjFree(obj);
virDomainObjUnref(obj);
VIR_FREE(statusFile);
return NULL;
}

View File

@ -640,6 +640,7 @@ typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj {
virMutex lock;
int refs;
int monitor;
virDomainChrDefPtr monitor_chr;
@ -697,7 +698,9 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def);
void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
void virDomainDefFree(virDomainDefPtr vm);
void virDomainObjFree(virDomainObjPtr vm);
void virDomainObjRef(virDomainObjPtr vm);
/* Returns 1 if the object was freed, 0 if more refs exist */
int virDomainObjUnref(virDomainObjPtr vm);
virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
virCapsPtr caps,

View File

@ -123,7 +123,6 @@ virDomainLifecycleTypeToString;
virDomainLoadAllConfigs;
virDomainNetDefFree;
virDomainNetTypeToString;
virDomainObjFree;
virDomainRemoveInactive;
virDomainSaveXML;
virDomainSaveConfig;
@ -152,6 +151,8 @@ virDomainObjListGetActiveIDs;
virDomainObjListNumOfDomains;
virDomainObjListInit;
virDomainObjListDeinit;
virDomainObjRef;
virDomainObjUnref;
# domain_event.h

View File

@ -463,6 +463,8 @@ int openvzLoadDomains(struct openvz_driver *driver) {
goto cleanup;
}
virDomainObjLock(dom);
if (VIR_ALLOC(dom->def) < 0)
goto no_memory;
@ -471,6 +473,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
else
dom->state = VIR_DOMAIN_RUNNING;
dom->refs = 1;
dom->pid = veid;
dom->def->id = dom->state == VIR_DOMAIN_SHUTOFF ? -1 : veid;
@ -513,6 +516,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
if (virHashAddEntry(driver->domains.objs, uuidstr, dom) < 0)
goto no_memory;
virDomainObjUnlock(dom);
dom = NULL;
}
@ -525,7 +529,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
cleanup:
fclose(fp);
virDomainObjFree(dom);
virDomainObjUnref(dom);
return -1;
}