[libvirt] [PATCH 03/16] Add callback to virNetClient to be invoked on EOF
Daniel Veillard
veillard at redhat.com
Thu Jul 19 08:18:33 UTC 2012
On Wed, Jul 18, 2012 at 05:32:24PM +0100, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at 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 at 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 at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list