1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-20 07:59:00 +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) static void virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
{ {
virDomainObjPtr obj = payload; virDomainObjPtr obj = payload;
virDomainObjFree(obj); virDomainObjLock(obj);
if (!virDomainObjUnref(obj))
virDomainObjUnlock(obj);
} }
void virDomainObjListDeinit(virDomainObjListPtr doms) void virDomainObjListDeinit(virDomainObjListPtr doms)
@ -602,11 +604,12 @@ void virDomainDefFree(virDomainDefPtr def)
#ifndef PROXY #ifndef PROXY
void virDomainObjFree(virDomainObjPtr dom) static void virDomainObjFree(virDomainObjPtr dom)
{ {
if (!dom) if (!dom)
return; return;
VIR_DEBUG("obj=%p", dom);
virDomainDefFree(dom->def); virDomainDefFree(dom->def);
virDomainDefFree(dom->newDef); virDomainDefFree(dom->newDef);
@ -622,6 +625,25 @@ void virDomainObjFree(virDomainObjPtr dom)
VIR_FREE(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, static virDomainObjPtr virDomainObjNew(virConnectPtr conn,
virCapsPtr caps) virCapsPtr caps)
{ {
@ -653,7 +675,9 @@ static virDomainObjPtr virDomainObjNew(virConnectPtr conn,
domain->state = VIR_DOMAIN_SHUTOFF; domain->state = VIR_DOMAIN_SHUTOFF;
domain->monitorWatch = -1; domain->monitorWatch = -1;
domain->monitor = -1; domain->monitor = -1;
domain->refs = 1;
VIR_DEBUG("obj=%p", domain);
return domain; return domain;
} }
@ -3455,7 +3479,7 @@ static virDomainObjPtr virDomainObjParseXML(virConnectPtr conn,
error: error:
VIR_FREE(nodes); VIR_FREE(nodes);
virDomainChrDefFree(obj->monitor_chr); virDomainChrDefFree(obj->monitor_chr);
virDomainObjFree(obj); virDomainObjUnref(obj);
return NULL; return NULL;
} }
@ -5052,7 +5076,7 @@ static virDomainObjPtr virDomainLoadStatus(virConnectPtr conn,
return obj; return obj;
error: error:
virDomainObjFree(obj); virDomainObjUnref(obj);
VIR_FREE(statusFile); VIR_FREE(statusFile);
return NULL; return NULL;
} }

View File

@ -640,6 +640,7 @@ typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr; typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj { struct _virDomainObj {
virMutex lock; virMutex lock;
int refs;
int monitor; int monitor;
virDomainChrDefPtr monitor_chr; virDomainChrDefPtr monitor_chr;
@ -697,7 +698,9 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def);
void virDomainHostdevDefFree(virDomainHostdevDefPtr def); void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
void virDomainDeviceDefFree(virDomainDeviceDefPtr def); void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
void virDomainDefFree(virDomainDefPtr vm); 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, virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
virCapsPtr caps, virCapsPtr caps,

View File

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

View File

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