As descriped at https://www.spinics.net/linux/fedora/libvir/msg148562.html,
even when virConnectDomainEventRegisterAny returns -1 there is still a
scenario in which it will trigger the free callback. We fix the problem in the
following way:
(1) implement a function virObjectEventStateSetFreeCB to add freecallback.
(2) call virObjectEventStateSetFreeCB only if the event is successfully added.

Signed-off-by: fangying <fangyi...@huawei.com>
---
 src/conf/object_event.c    | 34 ++++++++++++++++++++++++++++++++++
 src/conf/object_event.h    |  7 +++++++
 src/libvirt_private.syms   |  2 +-
 src/remote/remote_driver.c |  4 ++--
 4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/src/conf/object_event.c b/src/conf/object_event.c
index e5f942f..a770978 100644
--- a/src/conf/object_event.c
+++ b/src/conf/object_event.c
@@ -923,6 +923,40 @@ virObjectEventStateRegisterID(virConnectPtr conn,
 
 
 /**
+ * virObjectEventStateSetFreeCB:
+ * @conn: connection to associate with callback
+ * @state: object event state
+ * @callbackID: ID of the function to remove from event
+ * @freecb: freecb to be added
+ *
+ * Add the callbalck function @freecb for @callbackID with connection @conn,
+ * from @state, for events.
+ */
+void
+virObjectEventStateSetFreeCB(virConnectPtr conn,
+                             virObjectEventStatePtr state,
+                             int callbackID,
+                             virFreeCallback freecb)
+{
+    size_t i;
+    virObjectEventCallbackListPtr cbList;
+
+    virObjectEventStateLock(state);
+    cbList = state->callbacks;
+    for (i = 0; i < cbList->count; i++) {
+        virObjectEventCallbackPtr cb = cbList->callbacks[i];
+
+        if (cb->callbackID == callbackID && cb->conn == conn) {
+            cb->freecb = freecb;
+            break;
+        }
+    }
+
+    virObjectEventStateUnlock(state);
+}
+
+
+/**
  * virObjectEventStateDeregisterID:
  * @conn: connection to associate with callback
  * @state: object event state
diff --git a/src/conf/object_event.h b/src/conf/object_event.h
index 7a9995e..a7d29a0 100644
--- a/src/conf/object_event.h
+++ b/src/conf/object_event.h
@@ -90,4 +90,11 @@ virObjectEventStateSetRemote(virConnectPtr conn,
                              int remoteID)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+void
+virObjectEventStateSetFreeCB(virConnectPtr conn,
+                             virObjectEventStatePtr state,
+                             int callbackID,
+                             virFreeCallback freecb)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
+
 #endif
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 429b095..e9d9cb6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -791,7 +791,7 @@ virObjectEventStateDeregisterID;
 virObjectEventStateEventID;
 virObjectEventStateNew;
 virObjectEventStateQueue;
-
+virObjectEventStateSetFreeCB;
 
 # conf/secret_conf.h
 virSecretDefFormat;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index d27e96f..71177bd 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -5947,7 +5947,7 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn,
 
     if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
                                                    dom, eventID, callback,
-                                                   opaque, freecb, false,
+                                                   opaque, NULL, false,
                                                    &callbackID,
                                                    priv->serverEventFilter)) < 
0)
         goto done;
@@ -5993,7 +5993,7 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn,
     }
 
     rv = callbackID;
-
+    virObjectEventStateSetFreeCB(conn, priv->eventState, callbackID, freecb);
  done:
     remoteDriverUnlock(priv);
     return rv;
-- 
2.10.0.windows.1


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

Reply via email to