Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
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