diff --git a/src/datatypes.h b/src/datatypes.h index 8ac9171e9f91c84cd13949239dee5988da9d1ff9..a303cdc8465ce4e7256c60f5a99f4e50e4e20850 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -191,6 +191,8 @@ struct _virConnect { virConnectCloseFunc closeCallback; void *closeOpaque; virFreeCallback closeFreeCallback; + bool closeDispatch; + unsigned closeUnregisterCount; int refs; /* reference count */ }; diff --git a/src/libvirt.c b/src/libvirt.c index e7bab13f0490dec3e4194f8a569cdcc39b8104de..8e789bef71dcd37276a797361b7d09ab2cbb63a6 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -18723,7 +18723,8 @@ int virConnectUnregisterCloseCallback(virConnectPtr conn, } conn->closeCallback = NULL; - if (conn->closeFreeCallback) + conn->closeUnregisterCount++; + if (!conn->closeDispatch && conn->closeFreeCallback) conn->closeFreeCallback(conn->closeOpaque); conn->closeFreeCallback = NULL; conn->closeOpaque = NULL; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a69e69a7bd233111d841c59a21cbc9c11631b515..9ac27b2e07dc5a76a9e39672704dec48abfe84fa 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -320,6 +320,32 @@ enum virDrvOpenRemoteFlags { }; +static void remoteClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED, + int reason, + void *opaque) +{ + virConnectPtr conn = opaque; + + virMutexLock(&conn->lock); + if (conn->closeCallback) { + virConnectCloseFunc closeCallback = conn->closeCallback; + void *closeOpaque = conn->closeOpaque; + virFreeCallback closeFreeCallback = conn->closeFreeCallback; + unsigned closeUnregisterCount = conn->closeUnregisterCount; + + VIR_DEBUG("Triggering connection close callback %p reason=%d", + conn->closeCallback, reason); + conn->closeDispatch = true; + virMutexUnlock(&conn->lock); + closeCallback(conn, reason, closeOpaque); + virMutexLock(&conn->lock); + conn->closeDispatch = false; + if (conn->closeUnregisterCount != closeUnregisterCount) + closeFreeCallback(closeOpaque); + } + virMutexUnlock(&conn->lock); +} + /* * URIs that this driver needs to handle: * @@ -667,6 +693,11 @@ doRemoteOpen (virConnectPtr conn, #endif /* WIN32 */ } /* switch (transport) */ + + virNetClientSetCloseCallback(priv->client, + remoteClientCloseFunc, + conn, NULL); + if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM, REMOTE_PROTOCOL_VERSION, remoteDomainEvents,