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:
parent
77cfcccfa8
commit
a340f9131a
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user