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@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list