
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 :|