From: "Daniel P. Berrange" <berrange(a)redhat.com>
Allow detection of socket close in virNetClient via an callback
function, triggered on any condition that causes the socket to
be close.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/rpc/virnetclient.c | 35 +++++++++++++++++++++++++++++++----
src/rpc/virnetclient.h | 9 +++++++++
2 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 33d4209..6bab93f 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -102,6 +102,10 @@ struct _virNetClient {
virKeepAlivePtr keepalive;
bool wantClose;
int closeReason;
+
+ virNetClientCloseFunc closeCb;
+ void *closeOpaque;
+ virFreeCallback closeFf;
};
@@ -125,6 +129,19 @@ static void virNetClientUnlock(virNetClientPtr client)
}
+void virNetClientSetCloseCallback(virNetClientPtr client,
+ virNetClientCloseFunc cb,
+ void *opaque,
+ virFreeCallback ff)
+{
+ virNetClientLock(client);
+ client->closeCb = cb;
+ client->closeOpaque = opaque;
+ client->closeFf = ff;
+ virNetClientUnlock(client);
+}
+
+
static void virNetClientIncomingEvent(virNetSocketPtr sock,
int events,
void *opaque);
@@ -463,6 +480,9 @@ void virNetClientFree(virNetClientPtr client)
return;
}
+ if (client->closeFf && client->closeOpaque)
+ client->closeFf(client->closeOpaque);
+
for (i = 0 ; i < client->nprograms ; i++)
virNetClientProgramFree(client->programs[i]);
VIR_FREE(client->programs);
@@ -519,12 +539,19 @@ virNetClientCloseLocked(virNetClientPtr client)
client->keepalive = NULL;
client->wantClose = false;
- if (ka) {
+ if (ka || client->closeCb) {
+ virNetClientCloseFunc closeCb = client->closeCb;
+ void *closeOpaque = client->closeOpaque;
+ int closeReason = client->closeReason;
client->refs++;
virNetClientUnlock(client);
- virKeepAliveStop(ka);
- virKeepAliveFree(ka);
+ if (ka) {
+ virKeepAliveStop(ka);
+ virKeepAliveFree(ka);
+ }
+ if (closeCb)
+ closeCb(client, closeReason, closeOpaque);
virNetClientLock(client);
client->refs--;
@@ -534,7 +561,7 @@ virNetClientCloseLocked(virNetClientPtr client)
static void virNetClientCloseInternal(virNetClientPtr client,
int reason)
{
- VIR_DEBUG("client=%p", client);
+ VIR_DEBUG("client=%p wantclose=%d", client, client ? client->wantClose :
false);
if (!client)
return;
diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h
index 13b4f96..5c6eb5f 100644
--- a/src/rpc/virnetclient.h
+++ b/src/rpc/virnetclient.h
@@ -51,6 +51,15 @@ virNetClientPtr virNetClientNewSSH(const char *nodename,
virNetClientPtr virNetClientNewExternal(const char **cmdargv);
+typedef void (*virNetClientCloseFunc)(virNetClientPtr client,
+ int reason,
+ void *opaque);
+
+void virNetClientSetCloseCallback(virNetClientPtr client,
+ virNetClientCloseFunc cb,
+ void *opaque,
+ virFreeCallback ff);
+
void virNetClientRef(virNetClientPtr client);
int virNetClientGetFD(virNetClientPtr client);
--
1.7.10.4