/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Test that poll handlers are not re-entrant in nested aio_poll()
 *
 * Copyright Red Hat
 *
 * Poll handlers are usually level-triggered. That means they continue firing
 * until the condition is reset (e.g. a virtqueue becomes empty). If a poll
 * handler calls nested aio_poll() before the condition is reset, then infinite
 * recursion occurs.
 *
 * aio_poll() is supposed to prevent this by disabling poll handlers in nested
 * aio_poll() calls. This test case checks that this is indeed what happens.
 */
#include "qemu/osdep.h"
#include "block/aio.h"
#include "qapi/error.h"

typedef struct {
    AioContext *ctx;

    /* This is the EventNotifier that drives the test */
    EventNotifier poll_notifier;

    /* This EventNotifier is only used to wake aio_poll() */
    EventNotifier dummy_notifier;

    bool nested;
} TestData;

static void io_read(EventNotifier *notifier)
{
    fprintf(stderr, "%s %p\n", __func__, notifier);
    event_notifier_test_and_clear(notifier);
}

static bool io_poll_true(void *opaque)
{
    fprintf(stderr, "%s %p\n", __func__, opaque);
    return true;
}

static bool io_poll_false(void *opaque)
{
    fprintf(stderr, "%s %p\n", __func__, opaque);
    return false;
}

static void io_poll_ready(EventNotifier *notifier)
{
    TestData *td = container_of(notifier, TestData, poll_notifier);

    fprintf(stderr, "> %s\n", __func__);

    g_assert(!td->nested);
    td->nested = true;

    /* Wake the following nested aio_poll() call */
    event_notifier_set(&td->dummy_notifier);

    /* This nested event loop must not call io_poll()/io_poll_ready() */
    g_assert(aio_poll(td->ctx, true));

    td->nested = false;

    fprintf(stderr, "< %s\n", __func__);
}

/* dummy_notifier never triggers */
static void io_poll_never_ready(EventNotifier *notifier)
{
    g_assert_not_reached();
}

static void test(void)
{
    TestData td = {
        .ctx = aio_context_new(&error_abort),
    };

    qemu_set_current_aio_context(td.ctx);

    /* Enable polling */
    aio_context_set_poll_params(td.ctx, 1000000, 2, 2, &error_abort);

    /*
     * The GSource is unused but this has the side-effect of changing the fdmon
     * that AioContext uses.
     */
    aio_get_g_source(td.ctx);

    /* Make the event notifier active (set) right away */
    event_notifier_init(&td.poll_notifier, 1);
    aio_set_event_notifier(td.ctx, &td.poll_notifier,
                           io_read, io_poll_true, io_poll_ready);

    /* This event notifier will be used later */
    event_notifier_init(&td.dummy_notifier, 0);
    aio_set_event_notifier(td.ctx, &td.dummy_notifier,
                           io_read, io_poll_false, io_poll_never_ready);

    /* Consume aio_notify() */
    g_assert(!aio_poll(td.ctx, false));

    /*
     * Run the io_read() handler. This has the side-effect of activating
     * polling in future aio_poll() calls.
     */
    g_assert(aio_poll(td.ctx, true));

    /* The second time around the io_poll()/io_poll_ready() handler runs */
    g_assert(aio_poll(td.ctx, true));

    /* Run io_poll()/io_poll_ready() one more time to show it keeps working */
    g_assert(aio_poll(td.ctx, true));

    aio_set_event_notifier(td.ctx, &td.dummy_notifier, NULL, NULL, NULL);
    aio_set_event_notifier(td.ctx, &td.poll_notifier, NULL, NULL, NULL);
    event_notifier_cleanup(&td.dummy_notifier);
    event_notifier_cleanup(&td.poll_notifier);
    aio_context_unref(td.ctx);
}

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);
    g_test_add_func("/nested-aio-poll", test);
    return g_test_run();
}
