From: Frediano Ziglio Date: Thu, 13 Jun 2013 15:35:11 +0000 (+0100) Subject: Implement dispose method for libxlDomainObjPrivate X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d58ce13612837138a70291d7bab24128b5e9a255;p=libvirt.git Implement dispose method for libxlDomainObjPrivate When creating a timer/event handler reference counting is used. So it could be possible (in theory) that libxlDomainObjPrivateFree is called with reference counting >1. The problem is that libxlDomainObjPrivateFree leave the object in an invalid state with ctx freed (but still having dandling pointer). This can lead timer/event handler to core. This patch implements a dispose method for libxlDomainObjPrivate, and moves freeing the libxl ctx to the dispose method, ensuring the ctx is valid while the object's reference count is > 0. Signed-off-by: Frediano Ziglio --- diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 935919b153..9a7cb20415 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -110,6 +110,9 @@ static int libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, bool start_paused, int restore_fd); +static void +libxlDomainObjPrivateDispose(void *obj); + /* Function definitions */ static int libxlDomainObjPrivateOnceInit(void) @@ -117,7 +120,7 @@ libxlDomainObjPrivateOnceInit(void) if (!(libxlDomainObjPrivateClass = virClassNew(virClassForObjectLockable(), "libxlDomainObjPrivate", sizeof(libxlDomainObjPrivate), - NULL))) + libxlDomainObjPrivateDispose))) return -1; return 0; @@ -418,14 +421,26 @@ libxlDomainObjPrivateAlloc(void) } static void -libxlDomainObjPrivateFree(void *data) +libxlDomainObjPrivateDispose(void *obj) { - libxlDomainObjPrivatePtr priv = data; + libxlDomainObjPrivatePtr priv = obj; if (priv->deathW) libxl_evdisable_domain_death(priv->ctx, priv->deathW); libxl_ctx_free(priv->ctx); +} + +static void +libxlDomainObjPrivateFree(void *data) +{ + libxlDomainObjPrivatePtr priv = data; + + if (priv->deathW) { + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + priv->deathW = NULL; + } + virObjectUnref(priv); }