On Wed, Jul 18, 2012 at 05:32:24PM +0100, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berra...@redhat.com>
> 
> Allow detection of EOF in virNetClient via an callback
> function, triggered from the socket event handler
> 
> Signed-off-by: Daniel P. Berrange <berra...@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/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to