Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- po/POTFILES.in | 1 + src/datatypes.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ src/datatypes.h | 10 +++++++ src/libvirt-host.c | 35 ++-------------------- src/remote/remote_driver.c | 17 ++--------- 5 files changed, 91 insertions(+), 47 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 82e8d3e..176b60d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,6 +43,7 @@ src/cpu/cpu_generic.c src/cpu/cpu_map.c src/cpu/cpu_ppc64.c src/cpu/cpu_x86.c +src/datatypes.c src/driver.c src/esx/esx_driver.c src/esx/esx_network_driver.c diff --git a/src/datatypes.c b/src/datatypes.c index c832d80..3750557 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -180,6 +180,81 @@ virConnectCloseCallbackDataDispose(void *obj) virObjectUnlock(cb); } +int virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close, + virConnectPtr conn, + virConnectCloseFunc cb, + void *opaque, + virFreeCallback freecb) +{ + int ret = -1; + + virObjectLock(close); + + if (close->callback) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("A close callback is already registered")); + goto error; + } + + close->conn = conn; + virObjectRef(close->conn); + close->callback = cb; + close->opaque = opaque; + close->freeCallback = freecb; + + ret = 0; + + error: + virObjectUnlock(close); + return ret; +} + +int virConnectCloseCallbackDataUnregister(virConnectCloseCallbackDataPtr close, + virConnectCloseFunc cb) +{ + int ret = -1; + + virObjectLock(close); + + if (close->callback != cb) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("A different callback was requested")); + goto error; + } + + close->callback = NULL; + if (close->freeCallback) + close->freeCallback(close->opaque); + close->freeCallback = NULL; + virObjectUnref(close->conn); + + ret = 0; + + error: + virObjectUnlock(close); + return ret; +} + +void virConnectCloseCallbackDataCall(virConnectCloseCallbackDataPtr close, + int reason) +{ + virObjectLock(close); + + if (!close->callback) + goto exit; + + VIR_DEBUG("Triggering connection close callback %p reason=%d, opaque=%p", + close->callback, reason, close->opaque); + close->callback(close->conn, reason, close->opaque); + + if (close->freeCallback) + close->freeCallback(close->opaque); + close->callback = NULL; + close->freeCallback = NULL; + + exit: + virObjectUnlock(close); +} /** * virGetDomain: diff --git a/src/datatypes.h b/src/datatypes.h index 1b1777d..096f80f 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -601,4 +601,14 @@ virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain, virAdmConnectPtr virAdmConnectNew(void); +int virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close, + virConnectPtr conn, + virConnectCloseFunc cb, + void *opaque, + virFreeCallback freecb); +int virConnectCloseCallbackDataUnregister(virConnectCloseCallbackDataPtr close, + virConnectCloseFunc cb); +void virConnectCloseCallbackDataCall(virConnectCloseCallbackDataPtr close, + int reason); + #endif /* __VIR_DATATYPES_H__ */ diff --git a/src/libvirt-host.c b/src/libvirt-host.c index 9c88426..c492bd8 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1216,35 +1216,20 @@ virConnectRegisterCloseCallback(virConnectPtr conn, virResetLastError(); virCheckConnectReturn(conn, -1); - - virObjectRef(conn); - virObjectLock(conn); - virObjectLock(conn->closeCallback); virCheckNonNullArgGoto(cb, error); - if (conn->closeCallback->callback) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("A close callback is already registered")); + if (virConnectCloseCallbackDataRegister(conn->closeCallback, conn, cb, + opaque, freecb) < 0) goto error; - } - - conn->closeCallback->conn = conn; - conn->closeCallback->callback = cb; - conn->closeCallback->opaque = opaque; - conn->closeCallback->freeCallback = freecb; - virObjectUnlock(conn->closeCallback); virObjectUnlock(conn); - return 0; error: - virObjectUnlock(conn->closeCallback); virObjectUnlock(conn); virDispatchError(conn); - virObjectUnref(conn); return -1; } @@ -1271,31 +1256,17 @@ virConnectUnregisterCloseCallback(virConnectPtr conn, virResetLastError(); virCheckConnectReturn(conn, -1); - virObjectLock(conn); - virObjectLock(conn->closeCallback); virCheckNonNullArgGoto(cb, error); - if (conn->closeCallback->callback != cb) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("A different callback was requested")); + if (virConnectCloseCallbackDataUnregister(conn->closeCallback, cb) < 0) goto error; - } - conn->closeCallback->callback = NULL; - if (conn->closeCallback->freeCallback) - conn->closeCallback->freeCallback(conn->closeCallback->opaque); - conn->closeCallback->freeCallback = NULL; - - virObjectUnlock(conn->closeCallback); virObjectUnlock(conn); - virObjectUnref(conn); - return 0; error: - virObjectUnlock(conn->closeCallback); virObjectUnlock(conn); virDispatchError(conn); return -1; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a1dd640..f64c678 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -531,21 +531,8 @@ remoteClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED, int reason, void *opaque) { - virConnectCloseCallbackDataPtr cbdata = opaque; - - virObjectLock(cbdata); - - if (cbdata->callback) { - VIR_DEBUG("Triggering connection close callback %p reason=%d, opaque=%p", - cbdata->callback, reason, cbdata->opaque); - cbdata->callback(cbdata->conn, reason, cbdata->opaque); - - if (cbdata->freeCallback) - cbdata->freeCallback(cbdata->opaque); - cbdata->callback = NULL; - cbdata->freeCallback = NULL; - } - virObjectUnlock(cbdata); + virConnectCloseCallbackDataCall((virConnectCloseCallbackDataPtr)opaque, + reason); } /* helper macro to ease extraction of arguments from the URI */ -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list