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