[PATCH 3/4] datatypes: Introduce some admin-related close callback handling helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Well, there were three different spots where closeCallback->freeCallback was
called, not looking the same --> potential for bugs - and there indeed is a bug
with refcounting of the @conn object. So this patch partially follows the path
set by commit 24dbb69f by introducing some close callback helpers both to
replace all the spots where we call clean the close callback data with a
dedicated function and to be able to fix the refcounting bug causing a memleak.

Signed-off-by: Erik Skultety <eskultet@xxxxxxxxxx>
---
 po/POTFILES.in                 |  1 +
 src/datatypes.c                | 62 ++++++++++++++++++++++++++++++++++++++++++
 src/datatypes.h                |  8 ++++++
 src/libvirt_admin_private.syms |  3 ++
 4 files changed, 74 insertions(+)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1469240..5a37083 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -47,6 +47,7 @@ src/cpu/cpu_arm.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 ff0c46f..24e4f77 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -935,6 +935,68 @@ virAdmConnectCloseCallbackDataDispose(void *obj)
     virObjectUnlock(cb_data);
 }
 
+void
+virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackDataPtr cbdata)
+{
+    if (cbdata->freeCallback)
+        cbdata->freeCallback(cbdata->opaque);
+
+    virObjectUnref(cbdata->conn);
+    cbdata->conn = NULL;
+    cbdata->freeCallback = NULL;
+    cbdata->callback = NULL;
+    cbdata->opaque = NULL;
+}
+
+int
+virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackDataPtr cbdata,
+                                         virAdmConnectCloseFunc cb)
+{
+    int ret = -1;
+
+    virObjectLock(cbdata);
+    if (cbdata->callback != cb) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A different callback was requested"));
+        goto cleanup;
+    }
+
+    virAdmConnectCloseCallbackDataReset(cbdata);
+    ret = 0;
+ cleanup:
+    virObjectUnlock(cbdata);
+    return ret;
+}
+
+int
+virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackDataPtr cbdata,
+                                       virAdmConnectPtr conn,
+                                       virAdmConnectCloseFunc cb,
+                                       void *opaque,
+                                       virFreeCallback freecb)
+{
+    int ret = -1;
+
+    virObjectLock(cbdata);
+
+    if (cbdata->callback) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A close callback is already registered"));
+        goto cleanup;
+    }
+
+    virObjectRef(conn);
+    cbdata->conn = conn;
+    cbdata->callback = cb;
+    cbdata->opaque = opaque;
+    cbdata->freeCallback = freecb;
+
+    ret = 0;
+ cleanup:
+    virObjectUnlock(conn->closeCallback);
+    return ret;
+}
+
 virAdmServerPtr
 virAdmGetServer(virAdmConnectPtr conn, const char *name)
 {
diff --git a/src/datatypes.h b/src/datatypes.h
index 2b6adb4..9a5fbbc 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -722,5 +722,13 @@ void virConnectCloseCallbackDataCall(virConnectCloseCallbackDataPtr close,
                                      int reason);
 virConnectCloseFunc
 virConnectCloseCallbackDataGetCallback(virConnectCloseCallbackDataPtr close);
+void virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackDataPtr cbdata);
+int virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackDataPtr cbdata,
+                                           virAdmConnectPtr conn,
+                                           virAdmConnectCloseFunc cb,
+                                           void *opaque,
+                                           virFreeCallback freecb);
+int virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackDataPtr cbdata,
+                                             virAdmConnectCloseFunc cb);
 
 #endif /* __VIR_DATATYPES_H__ */
diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms
index 8c173ab..191e3f2 100644
--- a/src/libvirt_admin_private.syms
+++ b/src/libvirt_admin_private.syms
@@ -29,6 +29,9 @@ xdr_admin_server_set_threadpool_parameters_args;
 # datatypes.h
 virAdmClientClass;
 virAdmConnectClass;
+virAdmConnectCloseCallbackDataRegister;
+virAdmConnectCloseCallbackDataReset;
+virAdmConnectCloseCallbackDataUnregister;
 virAdmGetServer;
 virAdmServerClass;
 
-- 
2.5.5

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]