pcie: coding style tweak
[qemu/qmp-unstable.git] / tests / test-aio.c
blobe5f8b55d304bccf393e6a1fc18230cd669109db5
1 /*
2 * AioContext tests
4 * Copyright Red Hat, Inc. 2012
6 * Authors:
7 * Paolo Bonzini <pbonzini@redhat.com>
9 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
10 * See the COPYING.LIB file in the top-level directory.
13 #include <glib.h>
14 #include "block/aio.h"
15 #include "qemu/timer.h"
16 #include "qemu/sockets.h"
18 AioContext *ctx;
20 typedef struct {
21 EventNotifier e;
22 int n;
23 int active;
24 bool auto_set;
25 } EventNotifierTestData;
27 /* Wait until there are no more BHs or AIO requests */
28 static void wait_for_aio(void)
30 while (aio_poll(ctx, true)) {
31 /* Do nothing */
35 /* Wait until event notifier becomes inactive */
36 static void wait_until_inactive(EventNotifierTestData *data)
38 while (data->active > 0) {
39 aio_poll(ctx, true);
43 /* Simple callbacks for testing. */
45 typedef struct {
46 QEMUBH *bh;
47 int n;
48 int max;
49 } BHTestData;
51 typedef struct {
52 QEMUTimer timer;
53 QEMUClockType clock_type;
54 int n;
55 int max;
56 int64_t ns;
57 AioContext *ctx;
58 } TimerTestData;
60 static void bh_test_cb(void *opaque)
62 BHTestData *data = opaque;
63 if (++data->n < data->max) {
64 qemu_bh_schedule(data->bh);
68 #if !defined(_WIN32)
70 static void timer_test_cb(void *opaque)
72 TimerTestData *data = opaque;
73 if (++data->n < data->max) {
74 timer_mod(&data->timer,
75 qemu_clock_get_ns(data->clock_type) + data->ns);
79 static void dummy_io_handler_read(void *opaque)
83 #endif /* !_WIN32 */
85 static void bh_delete_cb(void *opaque)
87 BHTestData *data = opaque;
88 if (++data->n < data->max) {
89 qemu_bh_schedule(data->bh);
90 } else {
91 qemu_bh_delete(data->bh);
92 data->bh = NULL;
96 static void event_ready_cb(EventNotifier *e)
98 EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
99 g_assert(event_notifier_test_and_clear(e));
100 data->n++;
101 if (data->active > 0) {
102 data->active--;
104 if (data->auto_set && data->active) {
105 event_notifier_set(e);
109 /* Tests using aio_*. */
111 static void test_notify(void)
113 g_assert(!aio_poll(ctx, false));
114 aio_notify(ctx);
115 g_assert(!aio_poll(ctx, true));
116 g_assert(!aio_poll(ctx, false));
119 typedef struct {
120 QemuMutex start_lock;
121 bool thread_acquired;
122 } AcquireTestData;
124 static void *test_acquire_thread(void *opaque)
126 AcquireTestData *data = opaque;
128 /* Wait for other thread to let us start */
129 qemu_mutex_lock(&data->start_lock);
130 qemu_mutex_unlock(&data->start_lock);
132 aio_context_acquire(ctx);
133 aio_context_release(ctx);
135 data->thread_acquired = true; /* success, we got here */
137 return NULL;
140 static void dummy_notifier_read(EventNotifier *unused)
142 g_assert(false); /* should never be invoked */
145 static void test_acquire(void)
147 QemuThread thread;
148 EventNotifier notifier;
149 AcquireTestData data;
151 /* Dummy event notifier ensures aio_poll() will block */
152 event_notifier_init(&notifier, false);
153 aio_set_event_notifier(ctx, &notifier, dummy_notifier_read);
154 g_assert(!aio_poll(ctx, false)); /* consume aio_notify() */
156 qemu_mutex_init(&data.start_lock);
157 qemu_mutex_lock(&data.start_lock);
158 data.thread_acquired = false;
160 qemu_thread_create(&thread, "test_acquire_thread",
161 test_acquire_thread,
162 &data, QEMU_THREAD_JOINABLE);
164 /* Block in aio_poll(), let other thread kick us and acquire context */
165 aio_context_acquire(ctx);
166 qemu_mutex_unlock(&data.start_lock); /* let the thread run */
167 g_assert(!aio_poll(ctx, true));
168 aio_context_release(ctx);
170 qemu_thread_join(&thread);
171 aio_set_event_notifier(ctx, &notifier, NULL);
172 event_notifier_cleanup(&notifier);
174 g_assert(data.thread_acquired);
177 static void test_bh_schedule(void)
179 BHTestData data = { .n = 0 };
180 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
182 qemu_bh_schedule(data.bh);
183 g_assert_cmpint(data.n, ==, 0);
185 g_assert(aio_poll(ctx, true));
186 g_assert_cmpint(data.n, ==, 1);
188 g_assert(!aio_poll(ctx, false));
189 g_assert_cmpint(data.n, ==, 1);
190 qemu_bh_delete(data.bh);
193 static void test_bh_schedule10(void)
195 BHTestData data = { .n = 0, .max = 10 };
196 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
198 qemu_bh_schedule(data.bh);
199 g_assert_cmpint(data.n, ==, 0);
201 g_assert(aio_poll(ctx, false));
202 g_assert_cmpint(data.n, ==, 1);
204 g_assert(aio_poll(ctx, true));
205 g_assert_cmpint(data.n, ==, 2);
207 wait_for_aio();
208 g_assert_cmpint(data.n, ==, 10);
210 g_assert(!aio_poll(ctx, false));
211 g_assert_cmpint(data.n, ==, 10);
212 qemu_bh_delete(data.bh);
215 static void test_bh_cancel(void)
217 BHTestData data = { .n = 0 };
218 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
220 qemu_bh_schedule(data.bh);
221 g_assert_cmpint(data.n, ==, 0);
223 qemu_bh_cancel(data.bh);
224 g_assert_cmpint(data.n, ==, 0);
226 g_assert(!aio_poll(ctx, false));
227 g_assert_cmpint(data.n, ==, 0);
228 qemu_bh_delete(data.bh);
231 static void test_bh_delete(void)
233 BHTestData data = { .n = 0 };
234 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
236 qemu_bh_schedule(data.bh);
237 g_assert_cmpint(data.n, ==, 0);
239 qemu_bh_delete(data.bh);
240 g_assert_cmpint(data.n, ==, 0);
242 g_assert(!aio_poll(ctx, false));
243 g_assert_cmpint(data.n, ==, 0);
246 static void test_bh_delete_from_cb(void)
248 BHTestData data1 = { .n = 0, .max = 1 };
250 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
252 qemu_bh_schedule(data1.bh);
253 g_assert_cmpint(data1.n, ==, 0);
255 wait_for_aio();
256 g_assert_cmpint(data1.n, ==, data1.max);
257 g_assert(data1.bh == NULL);
259 g_assert(!aio_poll(ctx, false));
262 static void test_bh_delete_from_cb_many(void)
264 BHTestData data1 = { .n = 0, .max = 1 };
265 BHTestData data2 = { .n = 0, .max = 3 };
266 BHTestData data3 = { .n = 0, .max = 2 };
267 BHTestData data4 = { .n = 0, .max = 4 };
269 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
270 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
271 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
272 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
274 qemu_bh_schedule(data1.bh);
275 qemu_bh_schedule(data2.bh);
276 qemu_bh_schedule(data3.bh);
277 qemu_bh_schedule(data4.bh);
278 g_assert_cmpint(data1.n, ==, 0);
279 g_assert_cmpint(data2.n, ==, 0);
280 g_assert_cmpint(data3.n, ==, 0);
281 g_assert_cmpint(data4.n, ==, 0);
283 g_assert(aio_poll(ctx, false));
284 g_assert_cmpint(data1.n, ==, 1);
285 g_assert_cmpint(data2.n, ==, 1);
286 g_assert_cmpint(data3.n, ==, 1);
287 g_assert_cmpint(data4.n, ==, 1);
288 g_assert(data1.bh == NULL);
290 wait_for_aio();
291 g_assert_cmpint(data1.n, ==, data1.max);
292 g_assert_cmpint(data2.n, ==, data2.max);
293 g_assert_cmpint(data3.n, ==, data3.max);
294 g_assert_cmpint(data4.n, ==, data4.max);
295 g_assert(data1.bh == NULL);
296 g_assert(data2.bh == NULL);
297 g_assert(data3.bh == NULL);
298 g_assert(data4.bh == NULL);
301 static void test_bh_flush(void)
303 BHTestData data = { .n = 0 };
304 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
306 qemu_bh_schedule(data.bh);
307 g_assert_cmpint(data.n, ==, 0);
309 wait_for_aio();
310 g_assert_cmpint(data.n, ==, 1);
312 g_assert(!aio_poll(ctx, false));
313 g_assert_cmpint(data.n, ==, 1);
314 qemu_bh_delete(data.bh);
317 static void test_set_event_notifier(void)
319 EventNotifierTestData data = { .n = 0, .active = 0 };
320 event_notifier_init(&data.e, false);
321 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
322 g_assert(!aio_poll(ctx, false));
323 g_assert_cmpint(data.n, ==, 0);
325 aio_set_event_notifier(ctx, &data.e, NULL);
326 g_assert(!aio_poll(ctx, false));
327 g_assert_cmpint(data.n, ==, 0);
328 event_notifier_cleanup(&data.e);
331 static void test_wait_event_notifier(void)
333 EventNotifierTestData data = { .n = 0, .active = 1 };
334 event_notifier_init(&data.e, false);
335 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
336 g_assert(!aio_poll(ctx, false));
337 g_assert_cmpint(data.n, ==, 0);
338 g_assert_cmpint(data.active, ==, 1);
340 event_notifier_set(&data.e);
341 g_assert(aio_poll(ctx, false));
342 g_assert_cmpint(data.n, ==, 1);
343 g_assert_cmpint(data.active, ==, 0);
345 g_assert(!aio_poll(ctx, false));
346 g_assert_cmpint(data.n, ==, 1);
347 g_assert_cmpint(data.active, ==, 0);
349 aio_set_event_notifier(ctx, &data.e, NULL);
350 g_assert(!aio_poll(ctx, false));
351 g_assert_cmpint(data.n, ==, 1);
353 event_notifier_cleanup(&data.e);
356 static void test_flush_event_notifier(void)
358 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
359 event_notifier_init(&data.e, false);
360 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
361 g_assert(!aio_poll(ctx, false));
362 g_assert_cmpint(data.n, ==, 0);
363 g_assert_cmpint(data.active, ==, 10);
365 event_notifier_set(&data.e);
366 g_assert(aio_poll(ctx, false));
367 g_assert_cmpint(data.n, ==, 1);
368 g_assert_cmpint(data.active, ==, 9);
369 g_assert(aio_poll(ctx, false));
371 wait_until_inactive(&data);
372 g_assert_cmpint(data.n, ==, 10);
373 g_assert_cmpint(data.active, ==, 0);
374 g_assert(!aio_poll(ctx, false));
376 aio_set_event_notifier(ctx, &data.e, NULL);
377 g_assert(!aio_poll(ctx, false));
378 event_notifier_cleanup(&data.e);
381 static void test_wait_event_notifier_noflush(void)
383 EventNotifierTestData data = { .n = 0 };
384 EventNotifierTestData dummy = { .n = 0, .active = 1 };
386 event_notifier_init(&data.e, false);
387 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
389 g_assert(!aio_poll(ctx, false));
390 g_assert_cmpint(data.n, ==, 0);
392 /* Until there is an active descriptor, aio_poll may or may not call
393 * event_ready_cb. Still, it must not block. */
394 event_notifier_set(&data.e);
395 g_assert(aio_poll(ctx, true));
396 data.n = 0;
398 /* An active event notifier forces aio_poll to look at EventNotifiers. */
399 event_notifier_init(&dummy.e, false);
400 aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
402 event_notifier_set(&data.e);
403 g_assert(aio_poll(ctx, false));
404 g_assert_cmpint(data.n, ==, 1);
405 g_assert(!aio_poll(ctx, false));
406 g_assert_cmpint(data.n, ==, 1);
408 event_notifier_set(&data.e);
409 g_assert(aio_poll(ctx, false));
410 g_assert_cmpint(data.n, ==, 2);
411 g_assert(!aio_poll(ctx, false));
412 g_assert_cmpint(data.n, ==, 2);
414 event_notifier_set(&dummy.e);
415 wait_until_inactive(&dummy);
416 g_assert_cmpint(data.n, ==, 2);
417 g_assert_cmpint(dummy.n, ==, 1);
418 g_assert_cmpint(dummy.active, ==, 0);
420 aio_set_event_notifier(ctx, &dummy.e, NULL);
421 event_notifier_cleanup(&dummy.e);
423 aio_set_event_notifier(ctx, &data.e, NULL);
424 g_assert(!aio_poll(ctx, false));
425 g_assert_cmpint(data.n, ==, 2);
427 event_notifier_cleanup(&data.e);
430 #if !defined(_WIN32)
432 static void test_timer_schedule(void)
434 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
435 .max = 2,
436 .clock_type = QEMU_CLOCK_VIRTUAL };
437 int pipefd[2];
439 /* aio_poll will not block to wait for timers to complete unless it has
440 * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
442 g_assert(!qemu_pipe(pipefd));
443 qemu_set_nonblock(pipefd[0]);
444 qemu_set_nonblock(pipefd[1]);
446 aio_set_fd_handler(ctx, pipefd[0],
447 dummy_io_handler_read, NULL, NULL);
448 aio_poll(ctx, false);
450 aio_timer_init(ctx, &data.timer, data.clock_type,
451 SCALE_NS, timer_test_cb, &data);
452 timer_mod(&data.timer,
453 qemu_clock_get_ns(data.clock_type) +
454 data.ns);
456 g_assert_cmpint(data.n, ==, 0);
458 /* timer_mod may well cause an event notifer to have gone off,
459 * so clear that
461 do {} while (aio_poll(ctx, false));
463 g_assert(!aio_poll(ctx, false));
464 g_assert_cmpint(data.n, ==, 0);
466 g_usleep(1 * G_USEC_PER_SEC);
467 g_assert_cmpint(data.n, ==, 0);
469 g_assert(aio_poll(ctx, false));
470 g_assert_cmpint(data.n, ==, 1);
472 /* timer_mod called by our callback */
473 do {} while (aio_poll(ctx, false));
475 g_assert(!aio_poll(ctx, false));
476 g_assert_cmpint(data.n, ==, 1);
478 g_assert(aio_poll(ctx, true));
479 g_assert_cmpint(data.n, ==, 2);
481 /* As max is now 2, an event notifier should not have gone off */
483 g_assert(!aio_poll(ctx, false));
484 g_assert_cmpint(data.n, ==, 2);
486 aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
487 close(pipefd[0]);
488 close(pipefd[1]);
490 timer_del(&data.timer);
493 #endif /* !_WIN32 */
495 /* Now the same tests, using the context as a GSource. They are
496 * very similar to the ones above, with g_main_context_iteration
497 * replacing aio_poll. However:
498 * - sometimes both the AioContext and the glib main loop wake
499 * themselves up. Hence, some "g_assert(!aio_poll(ctx, false));"
500 * are replaced by "while (g_main_context_iteration(NULL, false));".
501 * - there is no exact replacement for a blocking wait.
502 * "while (g_main_context_iteration(NULL, true)" seems to work,
503 * but it is not documented _why_ it works. For these tests a
504 * non-blocking loop like "while (g_main_context_iteration(NULL, false)"
505 * works well, and that's what I am using.
508 static void test_source_notify(void)
510 while (g_main_context_iteration(NULL, false));
511 aio_notify(ctx);
512 g_assert(g_main_context_iteration(NULL, true));
513 g_assert(!g_main_context_iteration(NULL, false));
516 static void test_source_flush(void)
518 g_assert(!g_main_context_iteration(NULL, false));
519 aio_notify(ctx);
520 while (g_main_context_iteration(NULL, false));
521 g_assert(!g_main_context_iteration(NULL, false));
524 static void test_source_bh_schedule(void)
526 BHTestData data = { .n = 0 };
527 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
529 qemu_bh_schedule(data.bh);
530 g_assert_cmpint(data.n, ==, 0);
532 g_assert(g_main_context_iteration(NULL, true));
533 g_assert_cmpint(data.n, ==, 1);
535 g_assert(!g_main_context_iteration(NULL, false));
536 g_assert_cmpint(data.n, ==, 1);
537 qemu_bh_delete(data.bh);
540 static void test_source_bh_schedule10(void)
542 BHTestData data = { .n = 0, .max = 10 };
543 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
545 qemu_bh_schedule(data.bh);
546 g_assert_cmpint(data.n, ==, 0);
548 g_assert(g_main_context_iteration(NULL, false));
549 g_assert_cmpint(data.n, ==, 1);
551 g_assert(g_main_context_iteration(NULL, true));
552 g_assert_cmpint(data.n, ==, 2);
554 while (g_main_context_iteration(NULL, false));
555 g_assert_cmpint(data.n, ==, 10);
557 g_assert(!g_main_context_iteration(NULL, false));
558 g_assert_cmpint(data.n, ==, 10);
559 qemu_bh_delete(data.bh);
562 static void test_source_bh_cancel(void)
564 BHTestData data = { .n = 0 };
565 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
567 qemu_bh_schedule(data.bh);
568 g_assert_cmpint(data.n, ==, 0);
570 qemu_bh_cancel(data.bh);
571 g_assert_cmpint(data.n, ==, 0);
573 while (g_main_context_iteration(NULL, false));
574 g_assert_cmpint(data.n, ==, 0);
575 qemu_bh_delete(data.bh);
578 static void test_source_bh_delete(void)
580 BHTestData data = { .n = 0 };
581 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
583 qemu_bh_schedule(data.bh);
584 g_assert_cmpint(data.n, ==, 0);
586 qemu_bh_delete(data.bh);
587 g_assert_cmpint(data.n, ==, 0);
589 while (g_main_context_iteration(NULL, false));
590 g_assert_cmpint(data.n, ==, 0);
593 static void test_source_bh_delete_from_cb(void)
595 BHTestData data1 = { .n = 0, .max = 1 };
597 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
599 qemu_bh_schedule(data1.bh);
600 g_assert_cmpint(data1.n, ==, 0);
602 g_main_context_iteration(NULL, true);
603 g_assert_cmpint(data1.n, ==, data1.max);
604 g_assert(data1.bh == NULL);
606 g_assert(!g_main_context_iteration(NULL, false));
609 static void test_source_bh_delete_from_cb_many(void)
611 BHTestData data1 = { .n = 0, .max = 1 };
612 BHTestData data2 = { .n = 0, .max = 3 };
613 BHTestData data3 = { .n = 0, .max = 2 };
614 BHTestData data4 = { .n = 0, .max = 4 };
616 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
617 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
618 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
619 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
621 qemu_bh_schedule(data1.bh);
622 qemu_bh_schedule(data2.bh);
623 qemu_bh_schedule(data3.bh);
624 qemu_bh_schedule(data4.bh);
625 g_assert_cmpint(data1.n, ==, 0);
626 g_assert_cmpint(data2.n, ==, 0);
627 g_assert_cmpint(data3.n, ==, 0);
628 g_assert_cmpint(data4.n, ==, 0);
630 g_assert(g_main_context_iteration(NULL, false));
631 g_assert_cmpint(data1.n, ==, 1);
632 g_assert_cmpint(data2.n, ==, 1);
633 g_assert_cmpint(data3.n, ==, 1);
634 g_assert_cmpint(data4.n, ==, 1);
635 g_assert(data1.bh == NULL);
637 while (g_main_context_iteration(NULL, false));
638 g_assert_cmpint(data1.n, ==, data1.max);
639 g_assert_cmpint(data2.n, ==, data2.max);
640 g_assert_cmpint(data3.n, ==, data3.max);
641 g_assert_cmpint(data4.n, ==, data4.max);
642 g_assert(data1.bh == NULL);
643 g_assert(data2.bh == NULL);
644 g_assert(data3.bh == NULL);
645 g_assert(data4.bh == NULL);
648 static void test_source_bh_flush(void)
650 BHTestData data = { .n = 0 };
651 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
653 qemu_bh_schedule(data.bh);
654 g_assert_cmpint(data.n, ==, 0);
656 g_assert(g_main_context_iteration(NULL, true));
657 g_assert_cmpint(data.n, ==, 1);
659 g_assert(!g_main_context_iteration(NULL, false));
660 g_assert_cmpint(data.n, ==, 1);
661 qemu_bh_delete(data.bh);
664 static void test_source_set_event_notifier(void)
666 EventNotifierTestData data = { .n = 0, .active = 0 };
667 event_notifier_init(&data.e, false);
668 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
669 while (g_main_context_iteration(NULL, false));
670 g_assert_cmpint(data.n, ==, 0);
672 aio_set_event_notifier(ctx, &data.e, NULL);
673 while (g_main_context_iteration(NULL, false));
674 g_assert_cmpint(data.n, ==, 0);
675 event_notifier_cleanup(&data.e);
678 static void test_source_wait_event_notifier(void)
680 EventNotifierTestData data = { .n = 0, .active = 1 };
681 event_notifier_init(&data.e, false);
682 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
683 g_assert(g_main_context_iteration(NULL, false));
684 g_assert_cmpint(data.n, ==, 0);
685 g_assert_cmpint(data.active, ==, 1);
687 event_notifier_set(&data.e);
688 g_assert(g_main_context_iteration(NULL, false));
689 g_assert_cmpint(data.n, ==, 1);
690 g_assert_cmpint(data.active, ==, 0);
692 while (g_main_context_iteration(NULL, false));
693 g_assert_cmpint(data.n, ==, 1);
694 g_assert_cmpint(data.active, ==, 0);
696 aio_set_event_notifier(ctx, &data.e, NULL);
697 while (g_main_context_iteration(NULL, false));
698 g_assert_cmpint(data.n, ==, 1);
700 event_notifier_cleanup(&data.e);
703 static void test_source_flush_event_notifier(void)
705 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
706 event_notifier_init(&data.e, false);
707 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
708 g_assert(g_main_context_iteration(NULL, false));
709 g_assert_cmpint(data.n, ==, 0);
710 g_assert_cmpint(data.active, ==, 10);
712 event_notifier_set(&data.e);
713 g_assert(g_main_context_iteration(NULL, false));
714 g_assert_cmpint(data.n, ==, 1);
715 g_assert_cmpint(data.active, ==, 9);
716 g_assert(g_main_context_iteration(NULL, false));
718 while (g_main_context_iteration(NULL, false));
719 g_assert_cmpint(data.n, ==, 10);
720 g_assert_cmpint(data.active, ==, 0);
721 g_assert(!g_main_context_iteration(NULL, false));
723 aio_set_event_notifier(ctx, &data.e, NULL);
724 while (g_main_context_iteration(NULL, false));
725 event_notifier_cleanup(&data.e);
728 static void test_source_wait_event_notifier_noflush(void)
730 EventNotifierTestData data = { .n = 0 };
731 EventNotifierTestData dummy = { .n = 0, .active = 1 };
733 event_notifier_init(&data.e, false);
734 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
736 while (g_main_context_iteration(NULL, false));
737 g_assert_cmpint(data.n, ==, 0);
739 /* Until there is an active descriptor, glib may or may not call
740 * event_ready_cb. Still, it must not block. */
741 event_notifier_set(&data.e);
742 g_main_context_iteration(NULL, true);
743 data.n = 0;
745 /* An active event notifier forces aio_poll to look at EventNotifiers. */
746 event_notifier_init(&dummy.e, false);
747 aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
749 event_notifier_set(&data.e);
750 g_assert(g_main_context_iteration(NULL, false));
751 g_assert_cmpint(data.n, ==, 1);
752 g_assert(!g_main_context_iteration(NULL, false));
753 g_assert_cmpint(data.n, ==, 1);
755 event_notifier_set(&data.e);
756 g_assert(g_main_context_iteration(NULL, false));
757 g_assert_cmpint(data.n, ==, 2);
758 g_assert(!g_main_context_iteration(NULL, false));
759 g_assert_cmpint(data.n, ==, 2);
761 event_notifier_set(&dummy.e);
762 while (g_main_context_iteration(NULL, false));
763 g_assert_cmpint(data.n, ==, 2);
764 g_assert_cmpint(dummy.n, ==, 1);
765 g_assert_cmpint(dummy.active, ==, 0);
767 aio_set_event_notifier(ctx, &dummy.e, NULL);
768 event_notifier_cleanup(&dummy.e);
770 aio_set_event_notifier(ctx, &data.e, NULL);
771 while (g_main_context_iteration(NULL, false));
772 g_assert_cmpint(data.n, ==, 2);
774 event_notifier_cleanup(&data.e);
777 #if !defined(_WIN32)
779 static void test_source_timer_schedule(void)
781 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
782 .max = 2,
783 .clock_type = QEMU_CLOCK_VIRTUAL };
784 int pipefd[2];
785 int64_t expiry;
787 /* aio_poll will not block to wait for timers to complete unless it has
788 * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
790 g_assert(!qemu_pipe(pipefd));
791 qemu_set_nonblock(pipefd[0]);
792 qemu_set_nonblock(pipefd[1]);
794 aio_set_fd_handler(ctx, pipefd[0],
795 dummy_io_handler_read, NULL, NULL);
796 do {} while (g_main_context_iteration(NULL, false));
798 aio_timer_init(ctx, &data.timer, data.clock_type,
799 SCALE_NS, timer_test_cb, &data);
800 expiry = qemu_clock_get_ns(data.clock_type) +
801 data.ns;
802 timer_mod(&data.timer, expiry);
804 g_assert_cmpint(data.n, ==, 0);
806 g_usleep(1 * G_USEC_PER_SEC);
807 g_assert_cmpint(data.n, ==, 0);
809 g_assert(g_main_context_iteration(NULL, false));
810 g_assert_cmpint(data.n, ==, 1);
812 /* The comment above was not kidding when it said this wakes up itself */
813 do {
814 g_assert(g_main_context_iteration(NULL, true));
815 } while (qemu_clock_get_ns(data.clock_type) <= expiry);
816 g_usleep(1 * G_USEC_PER_SEC);
817 g_main_context_iteration(NULL, false);
819 g_assert_cmpint(data.n, ==, 2);
821 aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
822 close(pipefd[0]);
823 close(pipefd[1]);
825 timer_del(&data.timer);
828 #endif /* !_WIN32 */
831 /* End of tests. */
833 int main(int argc, char **argv)
835 GSource *src;
837 init_clocks();
839 ctx = aio_context_new();
840 src = aio_get_g_source(ctx);
841 g_source_attach(src, NULL);
842 g_source_unref(src);
844 while (g_main_context_iteration(NULL, false));
846 g_test_init(&argc, &argv, NULL);
847 g_test_add_func("/aio/notify", test_notify);
848 g_test_add_func("/aio/acquire", test_acquire);
849 g_test_add_func("/aio/bh/schedule", test_bh_schedule);
850 g_test_add_func("/aio/bh/schedule10", test_bh_schedule10);
851 g_test_add_func("/aio/bh/cancel", test_bh_cancel);
852 g_test_add_func("/aio/bh/delete", test_bh_delete);
853 g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb);
854 g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
855 g_test_add_func("/aio/bh/flush", test_bh_flush);
856 g_test_add_func("/aio/event/add-remove", test_set_event_notifier);
857 g_test_add_func("/aio/event/wait", test_wait_event_notifier);
858 g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush);
859 g_test_add_func("/aio/event/flush", test_flush_event_notifier);
860 #if !defined(_WIN32)
861 g_test_add_func("/aio/timer/schedule", test_timer_schedule);
862 #endif
864 g_test_add_func("/aio-gsource/notify", test_source_notify);
865 g_test_add_func("/aio-gsource/flush", test_source_flush);
866 g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule);
867 g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10);
868 g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel);
869 g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete);
870 g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb);
871 g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
872 g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush);
873 g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier);
874 g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier);
875 g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush);
876 g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier);
877 #if !defined(_WIN32)
878 g_test_add_func("/aio-gsource/timer/schedule", test_source_timer_schedule);
879 #endif
880 return g_test_run();