/* 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, false,
                           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, false,
                           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, false,
                           NULL, NULL, NULL);
    aio_set_event_notifier(td.ctx, &td.poll_notifier, false, 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();
}
