[libvirt] [PATCH 01/10] fdstream: Emit stream abort callback even if poll() doesnt.

Daniel P. Berrange berrange at redhat.com
Tue Oct 18 10:29:49 UTC 2011


On Wed, Oct 12, 2011 at 03:43:11PM +0200, Peter Krempa wrote:
> This patch causes the fdstream driver to call the stream event callback
> if virStreamAbort() is issued on a stream using this driver. This
> prohibited to abort streams from the daemon, as the daemon remote
> handler installs a callback to watch for stream errors as the only mean
> of detecting changes in the stream.
> ---
>  src/fdstream.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/src/fdstream.c b/src/fdstream.c
> index b60162c..8fb5e78 100644
> --- a/src/fdstream.c
> +++ b/src/fdstream.c
> @@ -55,6 +55,7 @@ struct virFDStreamData {
>      unsigned long long length;
> 
>      int watch;
> +    int events;         /* events the stream callback is subscribed for */
>      bool cbRemoved;
>      bool dispatching;
>      bool closed;
> @@ -62,6 +63,9 @@ struct virFDStreamData {
>      void *opaque;
>      virFreeCallback ff;
> 
> +    /* don't call the abort callback more than once */
> +    bool abortCallbackCalled;
> +
>      virMutex lock;
>  };
> 
> @@ -92,6 +96,7 @@ static int virFDStreamRemoveCallback(virStreamPtr stream)
>      fdst->watch = 0;
>      fdst->ff = NULL;
>      fdst->cb = NULL;
> +    fdst->events = 0;
>      fdst->opaque = NULL;
> 
>      ret = 0;
> @@ -120,6 +125,7 @@ static int virFDStreamUpdateCallback(virStreamPtr stream, int events)
>      }
> 
>      virEventUpdateHandle(fdst->watch, events);
> +    fdst->events = events;
> 
>      ret = 0;
> 
> @@ -214,6 +220,8 @@ virFDStreamAddCallback(virStreamPtr st,
>      fdst->cb = cb;
>      fdst->opaque = opaque;
>      fdst->ff = ff;
> +    fdst->events = events;
> +    fdst->abortCallbackCalled = false;
>      virStreamRef(st);
> 
>      ret = 0;
> @@ -223,18 +231,40 @@ cleanup:
>      return ret;
>  }
> 
> -
>  static int
> -virFDStreamClose(virStreamPtr st)
> +virFDStreamCloseInt(virStreamPtr st, bool streamAbort)
>  {
> -    struct virFDStreamData *fdst = st->privateData;
> +    struct virFDStreamData *fdst;
>      int ret;
> 
>      VIR_DEBUG("st=%p", st);
> 
> -    if (!fdst)
> +    if (!st || !(fdst = st->privateData))
>          return 0;
> 
> +    /* aborting the stream, ensure the callback is called if it's
> +     * registered for stream error event */
> +    if (streamAbort &&
> +        fdst->cb &&
> +        (fdst->events & VIR_STREAM_EVENT_ERROR)) {

You should be checking for 'READABLE | WRITABLE' here

> +        /* don't enter this function accidentaly from the callback again */
> +        virMutexLock(&fdst->lock);
> +        if (fdst->abortCallbackCalled) {
> +            virMutexUnlock(&fdst->lock);
> +            return 0;
> +        }
> +
> +        fdst->abortCallbackCalled = true;
> +        virMutexUnlock(&fdst->lock);
> +
> +        /* call failure callback, poll does report nothing on closed fd */
> +        (fdst->cb)(st, VIR_STREAM_EVENT_ERROR, fdst->opaque);

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list