
On Wed, Jul 18, 2012 at 05:32:24PM +0100, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Allow detection of EOF in virNetClient via an callback function, triggered from the socket event handler
Signed-off-by: Daniel P. Berrange <berrange@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; };
Initialized to NULL by virtue of VIR_ALLOC() in virNetClientNew()
@@ -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; + } }
What about the case ? if (client->haveTheBuck || client->wantClose) ? sure it's induced locally instead of getting raised by an 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);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/