]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add reference counting on virDomainObjPtr objects
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 15 Oct 2009 11:30:26 +0000 (12:30 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 10 Nov 2009 12:16:53 +0000 (12:16 +0000)
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

src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/openvz/openvz_conf.c

index 28bee54d519d56bfa31e0d79353e7860a781b1d6..25cb437eff01f13bdd024a2966b00f46d42d1d13 100644 (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;
 }
index fadf43f02346e8b7d88a0bcff8e4224f47bcae27..f12c722277cb6c67652e7ad9ff4128bf997f7f03 100644 (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,
index b360e7126f775e4c41a570306fee5f44abbf2d35..05068672cb09bfa6c7f27b92945bb0c052b4a0ee 100644 (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
index 6eeece899f75053ee2317df12c068c2cdaacacb3..f4c62f33f3644736cadf7d168681351f3846d512 100644 (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;
 }