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 <fangying1(a)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