aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Bligh <alex@alex.org.uk>2013-08-21 16:02:53 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2013-08-22 19:10:28 +0200
commit438e1f47e7db042a10458f70aaa6197aff5d84df (patch)
treee942f830632913e305223303d4934b861cf871eb
parent4e29e8311a53025a06433382768b82111c0bb80c (diff)
aio / timers: Convert aio_poll to use AioContext timers' deadline
Convert aio_poll to use deadline based on AioContext's timers. aio_poll has been changed to return accurately whether progress has occurred. Prior to this commit, aio_poll always returned true if g_poll was entered, whether or not any progress was made. This required a change to tests/test-aio.c where an assert was backwards. Signed-off-by: Alex Bligh <alex@alex.org.uk> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--aio-posix.c18
-rw-r--r--aio-win32.c20
2 files changed, 30 insertions, 8 deletions
diff --git a/aio-posix.c b/aio-posix.c
index 2440eb9c27..bd06f33c78 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -165,6 +165,10 @@ static bool aio_dispatch(AioContext *ctx)
g_free(tmp);
}
}
+
+ /* Run our timers */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+
return progress;
}
@@ -219,9 +223,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
}
/* wait until next event */
- ret = g_poll((GPollFD *)ctx->pollfds->data,
- ctx->pollfds->len,
- blocking ? -1 : 0);
+ ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
+ ctx->pollfds->len,
+ blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0);
/* if we have any readable fds, dispatch event */
if (ret > 0) {
@@ -232,9 +236,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
node->pfd.revents = pfd->revents;
}
}
- if (aio_dispatch(ctx)) {
- progress = true;
- }
+ }
+
+ /* Run dispatch even if there were no readable fds to run timers */
+ if (aio_dispatch(ctx)) {
+ progress = true;
}
return progress;
diff --git a/aio-win32.c b/aio-win32.c
index 78b2801c51..721fc252ab 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -95,6 +95,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
bool progress;
int count;
+ int timeout;
progress = false;
@@ -108,6 +109,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
progress = true;
}
+ /* Run timers */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+
/*
* Then dispatch any pending callbacks from the GSource.
*
@@ -164,8 +168,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
/* wait until next event */
while (count > 0) {
- int timeout = blocking ? INFINITE : 0;
- int ret = WaitForMultipleObjects(count, events, FALSE, timeout);
+ int ret;
+
+ timeout = blocking ?
+ qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg)) : 0;
+ ret = WaitForMultipleObjects(count, events, FALSE, timeout);
/* if we have any signaled events, dispatch event */
if ((DWORD) (ret - WAIT_OBJECT_0) >= count) {
@@ -208,5 +215,14 @@ bool aio_poll(AioContext *ctx, bool blocking)
events[ret - WAIT_OBJECT_0] = events[--count];
}
+ if (blocking) {
+ /* Run the timers a second time. We do this because otherwise aio_wait
+ * will not note progress - and will stop a drain early - if we have
+ * a timer that was not ready to run entering g_poll but is ready
+ * after g_poll. This will only do anything if a timer has expired.
+ */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+ }
+
return progress;
}