diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2013-04-11 16:56:50 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-08-19 15:45:35 +0200 |
commit | 164a101f28a53cd3db60ed874e7c3630e7988ed8 (patch) | |
tree | 02aafbb43ca0c97abc2c6b7b7a9ffc70f7d0b2b5 /aio-win32.c | |
parent | 35ecde26018207fe723bec6efbd340db6e9c2d53 (diff) | |
download | qemu-164a101f28a53cd3db60ed874e7c3630e7988ed8.zip qemu-164a101f28a53cd3db60ed874e7c3630e7988ed8.tar.gz qemu-164a101f28a53cd3db60ed874e7c3630e7988ed8.tar.bz2 |
aio: stop using .io_flush()
Now that aio_poll() users check their termination condition themselves,
it is no longer necessary to call .io_flush() handlers.
The behavior of aio_poll() changes as follows:
1. .io_flush() is no longer invoked and file descriptors are *always*
monitored. Previously returning 0 from .io_flush() would skip this file
descriptor.
Due to this change it is essential to check that requests are pending
before calling qemu_aio_wait(). Failure to do so means we block, for
example, waiting for an idle iSCSI socket to become readable when there
are no requests. Currently all qemu_aio_wait()/aio_poll() callers check
before calling.
2. aio_poll() now returns true if progress was made (BH or fd handlers
executed) and false otherwise. Previously it would return true whenever
'busy', which means that .io_flush() returned true. The 'busy' concept
no longer exists so just progress is returned.
Due to this change we need to update tests/test-aio.c which asserts
aio_poll() return values. Note that QEMU doesn't actually rely on these
return values so only tests/test-aio.c cares.
Note that ctx->notifier, the EventNotifier fd used for aio_notify(), is
now handled as a special case. This is a little ugly but maintains
aio_poll() semantics, i.e. aio_notify() does not count as 'progress' and
aio_poll() avoids blocking when the user has not set any fd handlers yet.
Patches after this remove .io_flush() handler code until we can finally
drop the io_flush arguments to aio_set_fd_handler() and friends.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'aio-win32.c')
-rw-r--r-- | aio-win32.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/aio-win32.c b/aio-win32.c index 38723bf..4309c16 100644 --- a/aio-win32.c +++ b/aio-win32.c @@ -23,7 +23,6 @@ struct AioHandler { EventNotifier *e; EventNotifierHandler *io_notify; - AioFlushEventNotifierHandler *io_flush; GPollFD pfd; int deleted; QLIST_ENTRY(AioHandler) node; @@ -73,7 +72,6 @@ void aio_set_event_notifier(AioContext *ctx, } /* Update handler with latest information */ node->io_notify = io_notify; - node->io_flush = io_flush; } aio_notify(ctx); @@ -96,7 +94,7 @@ bool aio_poll(AioContext *ctx, bool blocking) { AioHandler *node; HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; - bool busy, progress; + bool progress; int count; progress = false; @@ -126,7 +124,11 @@ bool aio_poll(AioContext *ctx, bool blocking) if (node->pfd.revents && node->io_notify) { node->pfd.revents = 0; node->io_notify(node->e); - progress = true; + + /* aio_notify() does not count as progress */ + if (node->opaque != &ctx->notifier) { + progress = true; + } } tmp = node; @@ -147,19 +149,8 @@ bool aio_poll(AioContext *ctx, bool blocking) ctx->walking_handlers++; /* fill fd sets */ - busy = false; count = 0; QLIST_FOREACH(node, &ctx->aio_handlers, node) { - /* If there aren't pending AIO operations, don't invoke callbacks. - * Otherwise, if there are no AIO requests, qemu_aio_wait() would - * wait indefinitely. - */ - if (!node->deleted && node->io_flush) { - if (node->io_flush(node->e) == 0) { - continue; - } - busy = true; - } if (!node->deleted && node->io_notify) { events[count++] = event_notifier_get_handle(node->e); } @@ -167,8 +158,8 @@ bool aio_poll(AioContext *ctx, bool blocking) ctx->walking_handlers--; - /* No AIO operations? Get us out of here */ - if (!busy) { + /* early return if we only have the aio_notify() fd */ + if (count == 1) { return progress; } @@ -196,7 +187,11 @@ bool aio_poll(AioContext *ctx, bool blocking) event_notifier_get_handle(node->e) == events[ret - WAIT_OBJECT_0] && node->io_notify) { node->io_notify(node->e); - progress = true; + + /* aio_notify() does not count as progress */ + if (node->opaque != &ctx->notifier) { + progress = true; + } } tmp = node; @@ -214,6 +209,5 @@ bool aio_poll(AioContext *ctx, bool blocking) events[ret - WAIT_OBJECT_0] = events[--count]; } - assert(progress || busy); - return true; + return progress; } |