Commit 438e1f47 authored by Alex Bligh's avatar Alex Bligh Committed by Stefan Hajnoczi
Browse files

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: default avatarAlex Bligh <alex@alex.org.uk>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 4e29e831
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -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,
    ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
                         ctx->pollfds->len,
                 blocking ? -1 : 0);
                         blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0);

    /* if we have any readable fds, dispatch event */
    if (ret > 0) {
@@ -232,10 +236,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
                node->pfd.revents = pfd->revents;
            }
        }
    }

    /* Run dispatch even if there were no readable fds to run timers */
    if (aio_dispatch(ctx)) {
        progress = true;
    }
    }

    return progress;
}
+18 −2
Original line number Diff line number Diff line
@@ -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;
}