]>
Commit | Line | Data |
---|---|---|
ed7db34b SH |
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 | ||
13 | static AioContext *ctx; | |
14 | ||
15 | static void dummy_fd_handler(EventNotifier *notifier) | |
16 | { | |
17 | event_notifier_test_and_clear(notifier); | |
18 | } | |
19 | ||
20 | static void add_event_notifiers(EventNotifier *notifiers, size_t n) | |
21 | { | |
22 | for (size_t i = 0; i < n; i++) { | |
23 | event_notifier_init(¬ifiers[i], false); | |
24 | aio_set_event_notifier(ctx, ¬ifiers[i], false, | |
25 | dummy_fd_handler, NULL); | |
26 | } | |
27 | } | |
28 | ||
29 | static 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, ¬ifiers[i], false, NULL, NULL); | |
33 | event_notifier_cleanup(¬ifiers[i]); | |
34 | } | |
35 | } | |
36 | ||
37 | /* Check that fd handlers work when external clients are disabled */ | |
38 | static 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(¬ifiers[0]); | |
46 | assert(aio_poll(ctx, true)); | |
47 | ||
48 | aio_disable_external(ctx); | |
49 | event_notifier_set(¬ifiers[0]); | |
50 | assert(aio_poll(ctx, true)); | |
51 | aio_enable_external(ctx); | |
52 | ||
53 | remove_event_notifiers(notifiers, G_N_ELEMENTS(notifiers)); | |
54 | } | |
55 | ||
56 | int 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 | } |