Skip to content

Commit

Permalink
aio / timers: Convert aio_poll to use AioContext timers' deadline
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
  • Loading branch information
abligh authored and stefanhaRH committed Aug 22, 2013
1 parent 4e29e83 commit 438e1f4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
18 changes: 12 additions & 6 deletions aio-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ static bool aio_dispatch(AioContext *ctx)
g_free(tmp);
}
}

/* Run our timers */
progress |= timerlistgroup_run_timers(&ctx->tlg);

return progress;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
20 changes: 18 additions & 2 deletions aio-win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.
*
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

0 comments on commit 438e1f4

Please sign in to comment.