aio / timers: Add test harness for AioContext timers
[qemu/ar7.git] / tests / test-aio.c
blob3ad22941d973bfd358a77bdf8e916195e0104a68
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"
17 AioContext *ctx;
19 typedef struct {
20 EventNotifier e;
21 int n;
22 int active;
23 bool auto_set;
24 } EventNotifierTestData;
26 /* Wait until there are no more BHs or AIO requests */
27 static void wait_for_aio(void)
29 while (aio_poll(ctx, true)) {
30 /* Do nothing */
34 /* Wait until event notifier becomes inactive */
35 static void wait_until_inactive(EventNotifierTestData *data)
37 while (data->active > 0) {
38 aio_poll(ctx, true);
42 /* Simple callbacks for testing. */
44 typedef struct {
45 QEMUBH *bh;
46 int n;
47 int max;
48 } BHTestData;
50 typedef struct {
51 QEMUTimer timer;
52 QEMUClockType clock_type;
53 int n;
54 int max;
55 int64_t ns;
56 AioContext *ctx;
57 } TimerTestData;
59 static void bh_test_cb(void *opaque)
61 BHTestData *data = opaque;
62 if (++data->n < data->max) {
63 qemu_bh_schedule(data->bh);
67 static void timer_test_cb(void *opaque)
69 TimerTestData *data = opaque;
70 if (++data->n < data->max) {
71 timer_mod(&data->timer,
72 qemu_clock_get_ns(data->clock_type) + data->ns);
76 static void dummy_io_handler_read(void *opaque)
80 static int dummy_io_handler_flush(void *opaque)
82 return 1;
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 static void test_bh_schedule(void)
121 BHTestData data = { .n = 0 };
122 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
124 qemu_bh_schedule(data.bh);
125 g_assert_cmpint(data.n, ==, 0);
127 g_assert(aio_poll(ctx, true));
128 g_assert_cmpint(data.n, ==, 1);
130 g_assert(!aio_poll(ctx, false));
131 g_assert_cmpint(data.n, ==, 1);
132 qemu_bh_delete(data.bh);
135 static void test_bh_schedule10(void)
137 BHTestData data = { .n = 0, .max = 10 };
138 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
140 qemu_bh_schedule(data.bh);
141 g_assert_cmpint(data.n, ==, 0);
143 g_assert(aio_poll(ctx, false));
144 g_assert_cmpint(data.n, ==, 1);
146 g_assert(aio_poll(ctx, true));
147 g_assert_cmpint(data.n, ==, 2);
149 wait_for_aio();
150 g_assert_cmpint(data.n, ==, 10);
152 g_assert(!aio_poll(ctx, false));
153 g_assert_cmpint(data.n, ==, 10);
154 qemu_bh_delete(data.bh);
157 static void test_bh_cancel(void)
159 BHTestData data = { .n = 0 };
160 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
162 qemu_bh_schedule(data.bh);
163 g_assert_cmpint(data.n, ==, 0);
165 qemu_bh_cancel(data.bh);
166 g_assert_cmpint(data.n, ==, 0);
168 g_assert(!aio_poll(ctx, false));
169 g_assert_cmpint(data.n, ==, 0);
170 qemu_bh_delete(data.bh);
173 static void test_bh_delete(void)
175 BHTestData data = { .n = 0 };
176 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
178 qemu_bh_schedule(data.bh);
179 g_assert_cmpint(data.n, ==, 0);
181 qemu_bh_delete(data.bh);
182 g_assert_cmpint(data.n, ==, 0);
184 g_assert(!aio_poll(ctx, false));
185 g_assert_cmpint(data.n, ==, 0);
188 static void test_bh_delete_from_cb(void)
190 BHTestData data1 = { .n = 0, .max = 1 };
192 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
194 qemu_bh_schedule(data1.bh);
195 g_assert_cmpint(data1.n, ==, 0);
197 wait_for_aio();
198 g_assert_cmpint(data1.n, ==, data1.max);
199 g_assert(data1.bh == NULL);
201 g_assert(!aio_poll(ctx, false));
202 g_assert(!aio_poll(ctx, true));
205 static void test_bh_delete_from_cb_many(void)
207 BHTestData data1 = { .n = 0, .max = 1 };
208 BHTestData data2 = { .n = 0, .max = 3 };
209 BHTestData data3 = { .n = 0, .max = 2 };
210 BHTestData data4 = { .n = 0, .max = 4 };
212 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
213 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
214 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
215 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
217 qemu_bh_schedule(data1.bh);
218 qemu_bh_schedule(data2.bh);
219 qemu_bh_schedule(data3.bh);
220 qemu_bh_schedule(data4.bh);
221 g_assert_cmpint(data1.n, ==, 0);
222 g_assert_cmpint(data2.n, ==, 0);
223 g_assert_cmpint(data3.n, ==, 0);
224 g_assert_cmpint(data4.n, ==, 0);
226 g_assert(aio_poll(ctx, false));
227 g_assert_cmpint(data1.n, ==, 1);
228 g_assert_cmpint(data2.n, ==, 1);
229 g_assert_cmpint(data3.n, ==, 1);
230 g_assert_cmpint(data4.n, ==, 1);
231 g_assert(data1.bh == NULL);
233 wait_for_aio();
234 g_assert_cmpint(data1.n, ==, data1.max);
235 g_assert_cmpint(data2.n, ==, data2.max);
236 g_assert_cmpint(data3.n, ==, data3.max);
237 g_assert_cmpint(data4.n, ==, data4.max);
238 g_assert(data1.bh == NULL);
239 g_assert(data2.bh == NULL);
240 g_assert(data3.bh == NULL);
241 g_assert(data4.bh == NULL);
244 static void test_bh_flush(void)
246 BHTestData data = { .n = 0 };
247 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
249 qemu_bh_schedule(data.bh);
250 g_assert_cmpint(data.n, ==, 0);
252 wait_for_aio();
253 g_assert_cmpint(data.n, ==, 1);
255 g_assert(!aio_poll(ctx, false));
256 g_assert_cmpint(data.n, ==, 1);
257 qemu_bh_delete(data.bh);
260 static void test_set_event_notifier(void)
262 EventNotifierTestData data = { .n = 0, .active = 0 };
263 event_notifier_init(&data.e, false);
264 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
265 g_assert(!aio_poll(ctx, false));
266 g_assert_cmpint(data.n, ==, 0);
268 aio_set_event_notifier(ctx, &data.e, NULL);
269 g_assert(!aio_poll(ctx, false));
270 g_assert_cmpint(data.n, ==, 0);
271 event_notifier_cleanup(&data.e);
274 static void test_wait_event_notifier(void)
276 EventNotifierTestData data = { .n = 0, .active = 1 };
277 event_notifier_init(&data.e, false);
278 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
279 g_assert(!aio_poll(ctx, false));
280 g_assert_cmpint(data.n, ==, 0);
281 g_assert_cmpint(data.active, ==, 1);
283 event_notifier_set(&data.e);
284 g_assert(aio_poll(ctx, false));
285 g_assert_cmpint(data.n, ==, 1);
286 g_assert_cmpint(data.active, ==, 0);
288 g_assert(!aio_poll(ctx, false));
289 g_assert_cmpint(data.n, ==, 1);
290 g_assert_cmpint(data.active, ==, 0);
292 aio_set_event_notifier(ctx, &data.e, NULL);
293 g_assert(!aio_poll(ctx, false));
294 g_assert_cmpint(data.n, ==, 1);
296 event_notifier_cleanup(&data.e);
299 static void test_flush_event_notifier(void)
301 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
302 event_notifier_init(&data.e, false);
303 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
304 g_assert(!aio_poll(ctx, false));
305 g_assert_cmpint(data.n, ==, 0);
306 g_assert_cmpint(data.active, ==, 10);
308 event_notifier_set(&data.e);
309 g_assert(aio_poll(ctx, false));
310 g_assert_cmpint(data.n, ==, 1);
311 g_assert_cmpint(data.active, ==, 9);
312 g_assert(aio_poll(ctx, false));
314 wait_until_inactive(&data);
315 g_assert_cmpint(data.n, ==, 10);
316 g_assert_cmpint(data.active, ==, 0);
317 g_assert(!aio_poll(ctx, false));
319 aio_set_event_notifier(ctx, &data.e, NULL);
320 g_assert(!aio_poll(ctx, false));
321 event_notifier_cleanup(&data.e);
324 static void test_wait_event_notifier_noflush(void)
326 EventNotifierTestData data = { .n = 0 };
327 EventNotifierTestData dummy = { .n = 0, .active = 1 };
329 event_notifier_init(&data.e, false);
330 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
332 g_assert(!aio_poll(ctx, false));
333 g_assert_cmpint(data.n, ==, 0);
335 /* Until there is an active descriptor, aio_poll may or may not call
336 * event_ready_cb. Still, it must not block. */
337 event_notifier_set(&data.e);
338 g_assert(aio_poll(ctx, true));
339 data.n = 0;
341 /* An active event notifier forces aio_poll to look at EventNotifiers. */
342 event_notifier_init(&dummy.e, false);
343 aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
345 event_notifier_set(&data.e);
346 g_assert(aio_poll(ctx, false));
347 g_assert_cmpint(data.n, ==, 1);
348 g_assert(!aio_poll(ctx, false));
349 g_assert_cmpint(data.n, ==, 1);
351 event_notifier_set(&data.e);
352 g_assert(aio_poll(ctx, false));
353 g_assert_cmpint(data.n, ==, 2);
354 g_assert(!aio_poll(ctx, false));
355 g_assert_cmpint(data.n, ==, 2);
357 event_notifier_set(&dummy.e);
358 wait_until_inactive(&dummy);
359 g_assert_cmpint(data.n, ==, 2);
360 g_assert_cmpint(dummy.n, ==, 1);
361 g_assert_cmpint(dummy.active, ==, 0);
363 aio_set_event_notifier(ctx, &dummy.e, NULL);
364 event_notifier_cleanup(&dummy.e);
366 aio_set_event_notifier(ctx, &data.e, NULL);
367 g_assert(!aio_poll(ctx, false));
368 g_assert_cmpint(data.n, ==, 2);
370 event_notifier_cleanup(&data.e);
373 static void test_timer_schedule(void)
375 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
376 .max = 2,
377 .clock_type = QEMU_CLOCK_VIRTUAL };
378 int pipefd[2];
380 /* aio_poll will not block to wait for timers to complete unless it has
381 * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
383 g_assert(!pipe2(pipefd, O_NONBLOCK));
384 aio_set_fd_handler(ctx, pipefd[0],
385 dummy_io_handler_read, NULL, dummy_io_handler_flush);
386 aio_poll(ctx, false);
388 aio_timer_init(ctx, &data.timer, data.clock_type,
389 SCALE_NS, timer_test_cb, &data);
390 timer_mod(&data.timer,
391 qemu_clock_get_ns(data.clock_type) +
392 data.ns);
394 g_assert_cmpint(data.n, ==, 0);
396 /* timer_mod may well cause an event notifer to have gone off,
397 * so clear that
399 do {} while (aio_poll(ctx, false));
401 g_assert(!aio_poll(ctx, false));
402 g_assert_cmpint(data.n, ==, 0);
404 sleep(1);
405 g_assert_cmpint(data.n, ==, 0);
407 g_assert(aio_poll(ctx, false));
408 g_assert_cmpint(data.n, ==, 1);
410 /* timer_mod called by our callback */
411 do {} while (aio_poll(ctx, false));
413 g_assert(!aio_poll(ctx, false));
414 g_assert_cmpint(data.n, ==, 1);
416 g_assert(aio_poll(ctx, true));
417 g_assert_cmpint(data.n, ==, 2);
419 /* As max is now 2, an event notifier should not have gone off */
421 g_assert(!aio_poll(ctx, false));
422 g_assert_cmpint(data.n, ==, 2);
424 aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
425 close(pipefd[0]);
426 close(pipefd[1]);
428 timer_del(&data.timer);
431 /* Now the same tests, using the context as a GSource. They are
432 * very similar to the ones above, with g_main_context_iteration
433 * replacing aio_poll. However:
434 * - sometimes both the AioContext and the glib main loop wake
435 * themselves up. Hence, some "g_assert(!aio_poll(ctx, false));"
436 * are replaced by "while (g_main_context_iteration(NULL, false));".
437 * - there is no exact replacement for a blocking wait.
438 * "while (g_main_context_iteration(NULL, true)" seems to work,
439 * but it is not documented _why_ it works. For these tests a
440 * non-blocking loop like "while (g_main_context_iteration(NULL, false)"
441 * works well, and that's what I am using.
444 static void test_source_notify(void)
446 while (g_main_context_iteration(NULL, false));
447 aio_notify(ctx);
448 g_assert(g_main_context_iteration(NULL, true));
449 g_assert(!g_main_context_iteration(NULL, false));
452 static void test_source_flush(void)
454 g_assert(!g_main_context_iteration(NULL, false));
455 aio_notify(ctx);
456 while (g_main_context_iteration(NULL, false));
457 g_assert(!g_main_context_iteration(NULL, false));
460 static void test_source_bh_schedule(void)
462 BHTestData data = { .n = 0 };
463 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
465 qemu_bh_schedule(data.bh);
466 g_assert_cmpint(data.n, ==, 0);
468 g_assert(g_main_context_iteration(NULL, true));
469 g_assert_cmpint(data.n, ==, 1);
471 g_assert(!g_main_context_iteration(NULL, false));
472 g_assert_cmpint(data.n, ==, 1);
473 qemu_bh_delete(data.bh);
476 static void test_source_bh_schedule10(void)
478 BHTestData data = { .n = 0, .max = 10 };
479 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
481 qemu_bh_schedule(data.bh);
482 g_assert_cmpint(data.n, ==, 0);
484 g_assert(g_main_context_iteration(NULL, false));
485 g_assert_cmpint(data.n, ==, 1);
487 g_assert(g_main_context_iteration(NULL, true));
488 g_assert_cmpint(data.n, ==, 2);
490 while (g_main_context_iteration(NULL, false));
491 g_assert_cmpint(data.n, ==, 10);
493 g_assert(!g_main_context_iteration(NULL, false));
494 g_assert_cmpint(data.n, ==, 10);
495 qemu_bh_delete(data.bh);
498 static void test_source_bh_cancel(void)
500 BHTestData data = { .n = 0 };
501 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
503 qemu_bh_schedule(data.bh);
504 g_assert_cmpint(data.n, ==, 0);
506 qemu_bh_cancel(data.bh);
507 g_assert_cmpint(data.n, ==, 0);
509 while (g_main_context_iteration(NULL, false));
510 g_assert_cmpint(data.n, ==, 0);
511 qemu_bh_delete(data.bh);
514 static void test_source_bh_delete(void)
516 BHTestData data = { .n = 0 };
517 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
519 qemu_bh_schedule(data.bh);
520 g_assert_cmpint(data.n, ==, 0);
522 qemu_bh_delete(data.bh);
523 g_assert_cmpint(data.n, ==, 0);
525 while (g_main_context_iteration(NULL, false));
526 g_assert_cmpint(data.n, ==, 0);
529 static void test_source_bh_delete_from_cb(void)
531 BHTestData data1 = { .n = 0, .max = 1 };
533 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
535 qemu_bh_schedule(data1.bh);
536 g_assert_cmpint(data1.n, ==, 0);
538 g_main_context_iteration(NULL, true);
539 g_assert_cmpint(data1.n, ==, data1.max);
540 g_assert(data1.bh == NULL);
542 g_assert(!g_main_context_iteration(NULL, false));
545 static void test_source_bh_delete_from_cb_many(void)
547 BHTestData data1 = { .n = 0, .max = 1 };
548 BHTestData data2 = { .n = 0, .max = 3 };
549 BHTestData data3 = { .n = 0, .max = 2 };
550 BHTestData data4 = { .n = 0, .max = 4 };
552 data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
553 data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
554 data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
555 data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
557 qemu_bh_schedule(data1.bh);
558 qemu_bh_schedule(data2.bh);
559 qemu_bh_schedule(data3.bh);
560 qemu_bh_schedule(data4.bh);
561 g_assert_cmpint(data1.n, ==, 0);
562 g_assert_cmpint(data2.n, ==, 0);
563 g_assert_cmpint(data3.n, ==, 0);
564 g_assert_cmpint(data4.n, ==, 0);
566 g_assert(g_main_context_iteration(NULL, false));
567 g_assert_cmpint(data1.n, ==, 1);
568 g_assert_cmpint(data2.n, ==, 1);
569 g_assert_cmpint(data3.n, ==, 1);
570 g_assert_cmpint(data4.n, ==, 1);
571 g_assert(data1.bh == NULL);
573 while (g_main_context_iteration(NULL, false));
574 g_assert_cmpint(data1.n, ==, data1.max);
575 g_assert_cmpint(data2.n, ==, data2.max);
576 g_assert_cmpint(data3.n, ==, data3.max);
577 g_assert_cmpint(data4.n, ==, data4.max);
578 g_assert(data1.bh == NULL);
579 g_assert(data2.bh == NULL);
580 g_assert(data3.bh == NULL);
581 g_assert(data4.bh == NULL);
584 static void test_source_bh_flush(void)
586 BHTestData data = { .n = 0 };
587 data.bh = aio_bh_new(ctx, bh_test_cb, &data);
589 qemu_bh_schedule(data.bh);
590 g_assert_cmpint(data.n, ==, 0);
592 g_assert(g_main_context_iteration(NULL, true));
593 g_assert_cmpint(data.n, ==, 1);
595 g_assert(!g_main_context_iteration(NULL, false));
596 g_assert_cmpint(data.n, ==, 1);
597 qemu_bh_delete(data.bh);
600 static void test_source_set_event_notifier(void)
602 EventNotifierTestData data = { .n = 0, .active = 0 };
603 event_notifier_init(&data.e, false);
604 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
605 while (g_main_context_iteration(NULL, false));
606 g_assert_cmpint(data.n, ==, 0);
608 aio_set_event_notifier(ctx, &data.e, NULL);
609 while (g_main_context_iteration(NULL, false));
610 g_assert_cmpint(data.n, ==, 0);
611 event_notifier_cleanup(&data.e);
614 static void test_source_wait_event_notifier(void)
616 EventNotifierTestData data = { .n = 0, .active = 1 };
617 event_notifier_init(&data.e, false);
618 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
619 g_assert(g_main_context_iteration(NULL, false));
620 g_assert_cmpint(data.n, ==, 0);
621 g_assert_cmpint(data.active, ==, 1);
623 event_notifier_set(&data.e);
624 g_assert(g_main_context_iteration(NULL, false));
625 g_assert_cmpint(data.n, ==, 1);
626 g_assert_cmpint(data.active, ==, 0);
628 while (g_main_context_iteration(NULL, false));
629 g_assert_cmpint(data.n, ==, 1);
630 g_assert_cmpint(data.active, ==, 0);
632 aio_set_event_notifier(ctx, &data.e, NULL);
633 while (g_main_context_iteration(NULL, false));
634 g_assert_cmpint(data.n, ==, 1);
636 event_notifier_cleanup(&data.e);
639 static void test_source_flush_event_notifier(void)
641 EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
642 event_notifier_init(&data.e, false);
643 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
644 g_assert(g_main_context_iteration(NULL, false));
645 g_assert_cmpint(data.n, ==, 0);
646 g_assert_cmpint(data.active, ==, 10);
648 event_notifier_set(&data.e);
649 g_assert(g_main_context_iteration(NULL, false));
650 g_assert_cmpint(data.n, ==, 1);
651 g_assert_cmpint(data.active, ==, 9);
652 g_assert(g_main_context_iteration(NULL, false));
654 while (g_main_context_iteration(NULL, false));
655 g_assert_cmpint(data.n, ==, 10);
656 g_assert_cmpint(data.active, ==, 0);
657 g_assert(!g_main_context_iteration(NULL, false));
659 aio_set_event_notifier(ctx, &data.e, NULL);
660 while (g_main_context_iteration(NULL, false));
661 event_notifier_cleanup(&data.e);
664 static void test_source_wait_event_notifier_noflush(void)
666 EventNotifierTestData data = { .n = 0 };
667 EventNotifierTestData dummy = { .n = 0, .active = 1 };
669 event_notifier_init(&data.e, false);
670 aio_set_event_notifier(ctx, &data.e, event_ready_cb);
672 while (g_main_context_iteration(NULL, false));
673 g_assert_cmpint(data.n, ==, 0);
675 /* Until there is an active descriptor, glib may or may not call
676 * event_ready_cb. Still, it must not block. */
677 event_notifier_set(&data.e);
678 g_main_context_iteration(NULL, true);
679 data.n = 0;
681 /* An active event notifier forces aio_poll to look at EventNotifiers. */
682 event_notifier_init(&dummy.e, false);
683 aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
685 event_notifier_set(&data.e);
686 g_assert(g_main_context_iteration(NULL, false));
687 g_assert_cmpint(data.n, ==, 1);
688 g_assert(!g_main_context_iteration(NULL, false));
689 g_assert_cmpint(data.n, ==, 1);
691 event_notifier_set(&data.e);
692 g_assert(g_main_context_iteration(NULL, false));
693 g_assert_cmpint(data.n, ==, 2);
694 g_assert(!g_main_context_iteration(NULL, false));
695 g_assert_cmpint(data.n, ==, 2);
697 event_notifier_set(&dummy.e);
698 while (g_main_context_iteration(NULL, false));
699 g_assert_cmpint(data.n, ==, 2);
700 g_assert_cmpint(dummy.n, ==, 1);
701 g_assert_cmpint(dummy.active, ==, 0);
703 aio_set_event_notifier(ctx, &dummy.e, NULL);
704 event_notifier_cleanup(&dummy.e);
706 aio_set_event_notifier(ctx, &data.e, NULL);
707 while (g_main_context_iteration(NULL, false));
708 g_assert_cmpint(data.n, ==, 2);
710 event_notifier_cleanup(&data.e);
713 static void test_source_timer_schedule(void)
715 TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
716 .max = 2,
717 .clock_type = QEMU_CLOCK_VIRTUAL };
718 int pipefd[2];
719 int64_t expiry;
721 /* aio_poll will not block to wait for timers to complete unless it has
722 * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
724 g_assert(!pipe2(pipefd, O_NONBLOCK));
725 aio_set_fd_handler(ctx, pipefd[0],
726 dummy_io_handler_read, NULL, dummy_io_handler_flush);
727 do {} while (g_main_context_iteration(NULL, false));
729 aio_timer_init(ctx, &data.timer, data.clock_type,
730 SCALE_NS, timer_test_cb, &data);
731 expiry = qemu_clock_get_ns(data.clock_type) +
732 data.ns;
733 timer_mod(&data.timer, expiry);
735 g_assert_cmpint(data.n, ==, 0);
737 sleep(1);
738 g_assert_cmpint(data.n, ==, 0);
740 g_assert(g_main_context_iteration(NULL, false));
741 g_assert_cmpint(data.n, ==, 1);
743 /* The comment above was not kidding when it said this wakes up itself */
744 do {
745 g_assert(g_main_context_iteration(NULL, true));
746 } while (qemu_clock_get_ns(data.clock_type) <= expiry);
747 sleep(1);
748 g_main_context_iteration(NULL, false);
750 g_assert_cmpint(data.n, ==, 2);
752 aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
753 close(pipefd[0]);
754 close(pipefd[1]);
756 timer_del(&data.timer);
760 /* End of tests. */
762 int main(int argc, char **argv)
764 GSource *src;
766 init_clocks();
768 ctx = aio_context_new();
769 src = aio_get_g_source(ctx);
770 g_source_attach(src, NULL);
771 g_source_unref(src);
773 while (g_main_context_iteration(NULL, false));
775 g_test_init(&argc, &argv, NULL);
776 g_test_add_func("/aio/notify", test_notify);
777 g_test_add_func("/aio/bh/schedule", test_bh_schedule);
778 g_test_add_func("/aio/bh/schedule10", test_bh_schedule10);
779 g_test_add_func("/aio/bh/cancel", test_bh_cancel);
780 g_test_add_func("/aio/bh/delete", test_bh_delete);
781 g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb);
782 g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
783 g_test_add_func("/aio/bh/flush", test_bh_flush);
784 g_test_add_func("/aio/event/add-remove", test_set_event_notifier);
785 g_test_add_func("/aio/event/wait", test_wait_event_notifier);
786 g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush);
787 g_test_add_func("/aio/event/flush", test_flush_event_notifier);
788 g_test_add_func("/aio/timer/schedule", test_timer_schedule);
790 g_test_add_func("/aio-gsource/notify", test_source_notify);
791 g_test_add_func("/aio-gsource/flush", test_source_flush);
792 g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule);
793 g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10);
794 g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel);
795 g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete);
796 g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb);
797 g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
798 g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush);
799 g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier);
800 g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier);
801 g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush);
802 g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier);
803 g_test_add_func("/aio-gsource/timer/schedule", test_source_timer_schedule);
804 return g_test_run();