On Wed, Jul 18, 2012 at 05:32:24PM +0100, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)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(a)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(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/