[libvirt] [PATCH 09/15] Add reference counting on virDomainObjPtr objects

Daniel Veillard veillard at redhat.com
Wed Nov 4 17:02:46 UTC 2009


On Tue, Nov 03, 2009 at 02:50:03PM -0500, Daniel P. Berrange wrote:
> 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   |   32 ++++++++++++++++++++++++++++----
>  src/conf/domain_conf.h   |    5 ++++-
>  src/libvirt_private.syms |    3 ++-
>  src/openvz/openvz_conf.c |    6 +++++-
>  4 files changed, 39 insertions(+), 7 deletions(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index a9c8573..79bb274 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -219,7 +219,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)
> @@ -582,11 +584,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);
>  
> @@ -602,6 +605,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)
>  {
> @@ -633,7 +655,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;
>  }
>  
> @@ -3305,7 +3329,7 @@ static virDomainObjPtr virDomainObjParseXML(virConnectPtr conn,
>  error:
>      VIR_FREE(nodes);
>      virDomainChrDefFree(obj->monitor_chr);
> -    virDomainObjFree(obj);
> +    virDomainObjUnref(obj);
>      return NULL;
>  }
>  
> @@ -4846,7 +4870,7 @@ static virDomainObjPtr virDomainLoadStatus(virConnectPtr conn,
>      return obj;
>  
>  error:
> -    virDomainObjFree(obj);
> +    virDomainObjUnref(obj);
>      VIR_FREE(statusFile);
>      return NULL;
>  }
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 8599ee7..675a49b 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -621,6 +621,7 @@ typedef struct _virDomainObj virDomainObj;
>  typedef virDomainObj *virDomainObjPtr;
>  struct _virDomainObj {
>      virMutex lock;
> +    int refs;
>  
>      int monitor;
>      virDomainChrDefPtr monitor_chr;
> @@ -678,7 +679,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,
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 600dfee..52f1a05 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -123,7 +123,6 @@ virDomainLifecycleTypeToString;
>  virDomainLoadAllConfigs;
>  virDomainNetDefFree;
>  virDomainNetTypeToString;
> -virDomainObjFree;
>  virDomainRemoveInactive;
>  virDomainSaveXML;
>  virDomainSaveConfig;
> @@ -151,6 +150,8 @@ virDomainObjListGetActiveIDs;
>  virDomainObjListNumOfDomains;
>  virDomainObjListInit;
>  virDomainObjListDeinit;
> +virDomainObjRef;
> +virDomainObjUnref;
>  
>  
>  # domain_event.h
> diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
> index c928afb..c2a39d0 100644
> --- a/src/openvz/openvz_conf.c
> +++ b/src/openvz/openvz_conf.c
> @@ -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;
>  }
>  

  ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list