On Wed, Jul 18, 2012 at 05:32:24PM +0100, Daniel P. Berrange wrote: > 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; > }; 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@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list