From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Allow detection of EOF in virNetClient via an callback function, triggered from the socket event handler Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list