[libvirt] [PATCH 3/5] Add callback to virNetClient to be invoked on connection close

Daniel P. Berrange berrange at redhat.com
Thu Jul 19 15:04:38 UTC 2012


From: "Daniel P. Berrange" <berrange at 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 at 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




More information about the libvir-list mailing list