]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add callback to virNetClient to be invoked on connection close
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 18 Jul 2012 16:10:22 +0000 (17:10 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 30 Jul 2012 09:08:41 +0000 (10:08 +0100)
Allow detection of socket close in virNetClient via a callback
function, triggered on any condition that causes the socket to
be closed.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/libvirt_private.syms
src/rpc/virnetclient.c
src/rpc/virnetclient.h

index 5672da109a3c70317688ec7927c3959d69a65dad..83ca99fcbb66f619bf1b92cd4a5316fdef1398ad 100644 (file)
@@ -1319,6 +1319,7 @@ virNetClientSendNoReply;
 virNetClientSendNonBlock;
 virNetClientSendWithReply;
 virNetClientSendWithReplyStream;
+virNetClientSetCloseCallback;
 virNetClientSetSASLSession;
 virNetClientSetTLSSession;
 
index a2587462a8362d75403dc39452a01bbcc2c7aae3..aba58ec1a2a97c07cf436c6ec772b5bfc744e788 100644 (file)
@@ -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->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;
index 3b8cbb254eed5fee8f248c8194e6318ada8ddfbb..c939475ffeb51d59dd87cac8ad3e8c894bbae6ac 100644 (file)
@@ -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);