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 :|
--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list