From: "Daniel P. Berrange" <berra...@redhat.com>

Allow detection of EOF in virNetClient via an callback
function, triggered from the socket event handler

Signed-off-by: Daniel P. Berrange <berra...@redhat.com>
---
 src/rpc/virnetclient.c |   43 +++++++++++++++++++++++++++++++++++++++----
 src/rpc/virnetclient.h |    8 ++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index f877934..326efb2 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -101,6 +101,11 @@ struct _virNetClient {
 
     virKeepAlivePtr keepalive;
     bool wantClose;
+
+
+    virNetClientEOFCallback eofCb;
+    void *eofOpaque;
+    virFreeCallback eofFf;
 };
 
 
@@ -122,6 +127,19 @@ static void virNetClientUnlock(virNetClientPtr client)
 }
 
 
+void virNetClientSetEOFNotify(virNetClientPtr client,
+                              virNetClientEOFCallback cb,
+                              void *opaque,
+                              virFreeCallback ff)
+{
+    virNetClientLock(client);
+    client->eofCb = cb;
+    client->eofOpaque = opaque;
+    client->eofFf = ff;
+    virNetClientUnlock(client);
+}
+
+
 static void virNetClientIncomingEvent(virNetSocketPtr sock,
                                       int events,
                                       void *opaque);
@@ -460,6 +478,9 @@ void virNetClientFree(virNetClientPtr client)
         return;
     }
 
+    if (client->eofFf && client->eofOpaque)
+        client->eofFf(client->eofOpaque);
+
     for (i = 0 ; i < client->nprograms ; i++)
         virNetClientProgramFree(client->programs[i]);
     VIR_FREE(client->programs);
@@ -1636,17 +1657,21 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
         VIR_DEBUG("%s : VIR_EVENT_HANDLE_HANGUP or "
                   "VIR_EVENT_HANDLE_ERROR encountered", __FUNCTION__);
         virNetSocketRemoveIOCallback(sock);
-        goto done;
+        goto eof;
     }
 
     if (events & VIR_EVENT_HANDLE_WRITABLE) {
-        if (virNetClientIOHandleOutput(client) < 0)
+        if (virNetClientIOHandleOutput(client) < 0) {
             virNetSocketRemoveIOCallback(sock);
+            goto eof;
+        }
     }
 
     if (events & VIR_EVENT_HANDLE_READABLE) {
-        if (virNetClientIOHandleInput(client) < 0)
+        if (virNetClientIOHandleInput(client) < 0) {
             virNetSocketRemoveIOCallback(sock);
+            goto eof;
+        }
     }
 
     /* Remove completed calls or signal their threads. */
@@ -1655,8 +1680,18 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
                                     NULL);
     virNetClientIOUpdateCallback(client, true);
 
-done:
     virNetClientUnlock(client);
+
+done:
+    return;
+
+eof:
+    if (client->eofCb) {
+        virNetClientEOFCallback eofCb = client->eofCb;
+        void *eofOpaque = client->eofOpaque;
+        virNetClientUnlock(client);
+        eofCb(client, eofOpaque);
+    }
 }
 
 
diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h
index 13b4f96..6e9219a 100644
--- a/src/rpc/virnetclient.h
+++ b/src/rpc/virnetclient.h
@@ -51,6 +51,14 @@ virNetClientPtr virNetClientNewSSH(const char *nodename,
 
 virNetClientPtr virNetClientNewExternal(const char **cmdargv);
 
+typedef void (*virNetClientEOFCallback)(virNetClientPtr client,
+                                        void *opaque);
+
+void virNetClientSetEOFNotify(virNetClientPtr client,
+                              virNetClientEOFCallback cb,
+                              void *opaque,
+                              virFreeCallback ff);
+
 void virNetClientRef(virNetClientPtr client);
 
 int virNetClientGetFD(virNetClientPtr client);
-- 
1.7.10.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to