qemu/tests/unit/test-fdmon-epoll.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * fdmon-epoll tests
   4 *
   5 * Copyright (c) 2020 Red Hat, Inc.
   6 */
   7
   8#include "qemu/osdep.h"
   9#include "block/aio.h"
  10#include "qapi/error.h"
  11#include "qemu/main-loop.h"
  12
  13static AioContext *ctx;
  14
  15static void dummy_fd_handler(EventNotifier *notifier)
  16{
  17    event_notifier_test_and_clear(notifier);
  18}
  19
  20static void add_event_notifiers(EventNotifier *notifiers, size_t n)
  21{
  22    for (size_t i = 0; i < n; i++) {
  23        event_notifier_init(&notifiers[i], false);
  24        aio_set_event_notifier(ctx, &notifiers[i], false,
  25                               dummy_fd_handler, NULL);
  26    }
  27}
  28
  29static void remove_event_notifiers(EventNotifier *notifiers, size_t n)
  30{
  31    for (size_t i = 0; i < n; i++) {
  32        aio_set_event_notifier(ctx, &notifiers[i], false, NULL, NULL);
  33        event_notifier_cleanup(&notifiers[i]);
  34    }
  35}
  36
  37/* Check that fd handlers work when external clients are disabled */
  38static void test_external_disabled(void)
  39{
  40    EventNotifier notifiers[100];
  41
  42    /* fdmon-epoll is only enabled when many fd handlers are registered */
  43    add_event_notifiers(notifiers, G_N_ELEMENTS(notifiers));
  44
  45    event_notifier_set(&notifiers[0]);
  46    assert(aio_poll(ctx, true));
  47
  48    aio_disable_external(ctx);
  49    event_notifier_set(&notifiers[0]);
  50    assert(aio_poll(ctx, true));
  51    aio_enable_external(ctx);
  52
  53    remove_event_notifiers(notifiers, G_N_ELEMENTS(notifiers));
  54}
  55
  56int main(int argc, char **argv)
  57{
  58    /*
  59     * This code relies on the fact that fdmon-io_uring disables itself when
  60     * the glib main loop is in use. The main loop uses fdmon-poll and upgrades
  61     * to fdmon-epoll when the number of fds exceeds a threshold.
  62     */
  63    qemu_init_main_loop(&error_fatal);
  64    ctx = qemu_get_aio_context();
  65
  66    while (g_main_context_iteration(NULL, false)) {
  67        /* Do nothing */
  68    }
  69
  70    g_test_init(&argc, &argv, NULL);
  71    g_test_add_func("/fdmon-epoll/external-disabled", test_external_disabled);
  72    return g_test_run();
  73}
  74