]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blob - tests/test-aio.c
test-aio: fix GSource-based timer test
[lisovros/qemu_apohw.git] / tests / test-aio.c
1 /*
2  * AioContext tests
3  *
4  * Copyright Red Hat, Inc. 2012
5  *
6  * Authors:
7  *  Paolo Bonzini    <pbonzini@redhat.com>
8  *
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.
11  */
12
13 #include <glib.h>
14 #include "block/aio.h"
15 #include "qemu/timer.h"
16 #include "qemu/sockets.h"
17
18 AioContext *ctx;
19
20 typedef struct {
21     EventNotifier e;
22     int n;
23     int active;
24     bool auto_set;
25 } EventNotifierTestData;
26
27 /* Wait until there are no more BHs or AIO requests */
28 static void wait_for_aio(void)
29 {
30     while (aio_poll(ctx, true)) {
31         /* Do nothing */
32     }
33 }
34
35 /* Wait until event notifier becomes inactive */
36 static void wait_until_inactive(EventNotifierTestData *data)
37 {
38     while (data->active > 0) {
39         aio_poll(ctx, true);
40     }
41 }
42
43 /* Simple callbacks for testing.  */
44
45 typedef struct {
46     QEMUBH *bh;
47     int n;
48     int max;
49 } BHTestData;
50
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;
59
60 static void bh_test_cb(void *opaque)
61 {
62     BHTestData *data = opaque;
63     if (++data->n < data->max) {
64         qemu_bh_schedule(data->bh);
65     }
66 }
67
68 #if !defined(_WIN32)
69
70 static void timer_test_cb(void *opaque)
71 {
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);
76     }
77 }
78
79 static void dummy_io_handler_read(void *opaque)
80 {
81 }
82
83 #endif /* !_WIN32 */
84
85 static void bh_delete_cb(void *opaque)
86 {
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;
93     }
94 }
95
96 static void event_ready_cb(EventNotifier *e)
97 {
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--;
103     }
104     if (data->auto_set && data->active) {
105         event_notifier_set(e);
106     }
107 }
108
109 /* Tests using aio_*.  */
110
111 static void test_notify(void)
112 {
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));
117 }
118
119 typedef struct {
120     QemuMutex start_lock;
121     bool thread_acquired;
122 } AcquireTestData;
123
124 static void *test_acquire_thread(void *opaque)
125 {
126     AcquireTestData *data = opaque;
127
128     /* Wait for other thread to let us start */
129     qemu_mutex_lock(&data->start_lock);
130     qemu_mutex_unlock(&data->start_lock);
131
132     aio_context_acquire(ctx);
133     aio_context_release(ctx);
134
135     data->thread_acquired = true; /* success, we got here */
136
137     return NULL;
138 }
139
140 static void dummy_notifier_read(EventNotifier *unused)
141 {
142     g_assert(false); /* should never be invoked */
143 }
144
145 static void test_acquire(void)
146 {
147     QemuThread thread;
148     EventNotifier notifier;
149     AcquireTestData data;
150
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() */
155
156     qemu_mutex_init(&data.start_lock);
157     qemu_mutex_lock(&data.start_lock);
158     data.thread_acquired = false;
159
160     qemu_thread_create(&thread, "test_acquire_thread",
161                        test_acquire_thread,
162                        &data, QEMU_THREAD_JOINABLE);
163
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);
169
170     qemu_thread_join(&thread);
171     aio_set_event_notifier(ctx, &notifier, NULL);
172     event_notifier_cleanup(&notifier);
173
174     g_assert(data.thread_acquired);
175 }
176
177 static void test_bh_schedule(void)
178 {
179     BHTestData data = { .n = 0 };
180     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
181
182     qemu_bh_schedule(data.bh);
183     g_assert_cmpint(data.n, ==, 0);
184
185     g_assert(aio_poll(ctx, true));
186     g_assert_cmpint(data.n, ==, 1);
187
188     g_assert(!aio_poll(ctx, false));
189     g_assert_cmpint(data.n, ==, 1);
190     qemu_bh_delete(data.bh);
191 }
192
193 static void test_bh_schedule10(void)
194 {
195     BHTestData data = { .n = 0, .max = 10 };
196     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
197
198     qemu_bh_schedule(data.bh);
199     g_assert_cmpint(data.n, ==, 0);
200
201     g_assert(aio_poll(ctx, false));
202     g_assert_cmpint(data.n, ==, 1);
203
204     g_assert(aio_poll(ctx, true));
205     g_assert_cmpint(data.n, ==, 2);
206
207     wait_for_aio();
208     g_assert_cmpint(data.n, ==, 10);
209
210     g_assert(!aio_poll(ctx, false));
211     g_assert_cmpint(data.n, ==, 10);
212     qemu_bh_delete(data.bh);
213 }
214
215 static void test_bh_cancel(void)
216 {
217     BHTestData data = { .n = 0 };
218     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
219
220     qemu_bh_schedule(data.bh);
221     g_assert_cmpint(data.n, ==, 0);
222
223     qemu_bh_cancel(data.bh);
224     g_assert_cmpint(data.n, ==, 0);
225
226     g_assert(!aio_poll(ctx, false));
227     g_assert_cmpint(data.n, ==, 0);
228     qemu_bh_delete(data.bh);
229 }
230
231 static void test_bh_delete(void)
232 {
233     BHTestData data = { .n = 0 };
234     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
235
236     qemu_bh_schedule(data.bh);
237     g_assert_cmpint(data.n, ==, 0);
238
239     qemu_bh_delete(data.bh);
240     g_assert_cmpint(data.n, ==, 0);
241
242     g_assert(!aio_poll(ctx, false));
243     g_assert_cmpint(data.n, ==, 0);
244 }
245
246 static void test_bh_delete_from_cb(void)
247 {
248     BHTestData data1 = { .n = 0, .max = 1 };
249
250     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
251
252     qemu_bh_schedule(data1.bh);
253     g_assert_cmpint(data1.n, ==, 0);
254
255     wait_for_aio();
256     g_assert_cmpint(data1.n, ==, data1.max);
257     g_assert(data1.bh == NULL);
258
259     g_assert(!aio_poll(ctx, false));
260 }
261
262 static void test_bh_delete_from_cb_many(void)
263 {
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 };
268
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);
273
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);
282
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);
289
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);
299 }
300
301 static void test_bh_flush(void)
302 {
303     BHTestData data = { .n = 0 };
304     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
305
306     qemu_bh_schedule(data.bh);
307     g_assert_cmpint(data.n, ==, 0);
308
309     wait_for_aio();
310     g_assert_cmpint(data.n, ==, 1);
311
312     g_assert(!aio_poll(ctx, false));
313     g_assert_cmpint(data.n, ==, 1);
314     qemu_bh_delete(data.bh);
315 }
316
317 static void test_set_event_notifier(void)
318 {
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);
324
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);
329 }
330
331 static void test_wait_event_notifier(void)
332 {
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);
339
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);
344
345     g_assert(!aio_poll(ctx, false));
346     g_assert_cmpint(data.n, ==, 1);
347     g_assert_cmpint(data.active, ==, 0);
348
349     aio_set_event_notifier(ctx, &data.e, NULL);
350     g_assert(!aio_poll(ctx, false));
351     g_assert_cmpint(data.n, ==, 1);
352
353     event_notifier_cleanup(&data.e);
354 }
355
356 static void test_flush_event_notifier(void)
357 {
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);
364
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));
370
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));
375
376     aio_set_event_notifier(ctx, &data.e, NULL);
377     g_assert(!aio_poll(ctx, false));
378     event_notifier_cleanup(&data.e);
379 }
380
381 static void test_wait_event_notifier_noflush(void)
382 {
383     EventNotifierTestData data = { .n = 0 };
384     EventNotifierTestData dummy = { .n = 0, .active = 1 };
385
386     event_notifier_init(&data.e, false);
387     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
388
389     g_assert(!aio_poll(ctx, false));
390     g_assert_cmpint(data.n, ==, 0);
391
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;
397
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);
401
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);
407
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);
413
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);
419
420     aio_set_event_notifier(ctx, &dummy.e, NULL);
421     event_notifier_cleanup(&dummy.e);
422
423     aio_set_event_notifier(ctx, &data.e, NULL);
424     g_assert(!aio_poll(ctx, false));
425     g_assert_cmpint(data.n, ==, 2);
426
427     event_notifier_cleanup(&data.e);
428 }
429
430 #if !defined(_WIN32)
431
432 static void test_timer_schedule(void)
433 {
434     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
435                            .max = 2,
436                            .clock_type = QEMU_CLOCK_VIRTUAL };
437     int pipefd[2];
438
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.
441      */
442     g_assert(!qemu_pipe(pipefd));
443     qemu_set_nonblock(pipefd[0]);
444     qemu_set_nonblock(pipefd[1]);
445
446     aio_set_fd_handler(ctx, pipefd[0],
447                        dummy_io_handler_read, NULL, NULL);
448     aio_poll(ctx, false);
449
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);
455
456     g_assert_cmpint(data.n, ==, 0);
457
458     /* timer_mod may well cause an event notifer to have gone off,
459      * so clear that
460      */
461     do {} while (aio_poll(ctx, false));
462
463     g_assert(!aio_poll(ctx, false));
464     g_assert_cmpint(data.n, ==, 0);
465
466     g_usleep(1 * G_USEC_PER_SEC);
467     g_assert_cmpint(data.n, ==, 0);
468
469     g_assert(aio_poll(ctx, false));
470     g_assert_cmpint(data.n, ==, 1);
471
472     /* timer_mod called by our callback */
473     do {} while (aio_poll(ctx, false));
474
475     g_assert(!aio_poll(ctx, false));
476     g_assert_cmpint(data.n, ==, 1);
477
478     g_assert(aio_poll(ctx, true));
479     g_assert_cmpint(data.n, ==, 2);
480
481     /* As max is now 2, an event notifier should not have gone off */
482
483     g_assert(!aio_poll(ctx, false));
484     g_assert_cmpint(data.n, ==, 2);
485
486     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
487     close(pipefd[0]);
488     close(pipefd[1]);
489
490     timer_del(&data.timer);
491 }
492
493 #endif /* !_WIN32 */
494
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.
506  */
507
508 static void test_source_notify(void)
509 {
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));
514 }
515
516 static void test_source_flush(void)
517 {
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));
522 }
523
524 static void test_source_bh_schedule(void)
525 {
526     BHTestData data = { .n = 0 };
527     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
528
529     qemu_bh_schedule(data.bh);
530     g_assert_cmpint(data.n, ==, 0);
531
532     g_assert(g_main_context_iteration(NULL, true));
533     g_assert_cmpint(data.n, ==, 1);
534
535     g_assert(!g_main_context_iteration(NULL, false));
536     g_assert_cmpint(data.n, ==, 1);
537     qemu_bh_delete(data.bh);
538 }
539
540 static void test_source_bh_schedule10(void)
541 {
542     BHTestData data = { .n = 0, .max = 10 };
543     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
544
545     qemu_bh_schedule(data.bh);
546     g_assert_cmpint(data.n, ==, 0);
547
548     g_assert(g_main_context_iteration(NULL, false));
549     g_assert_cmpint(data.n, ==, 1);
550
551     g_assert(g_main_context_iteration(NULL, true));
552     g_assert_cmpint(data.n, ==, 2);
553
554     while (g_main_context_iteration(NULL, false));
555     g_assert_cmpint(data.n, ==, 10);
556
557     g_assert(!g_main_context_iteration(NULL, false));
558     g_assert_cmpint(data.n, ==, 10);
559     qemu_bh_delete(data.bh);
560 }
561
562 static void test_source_bh_cancel(void)
563 {
564     BHTestData data = { .n = 0 };
565     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
566
567     qemu_bh_schedule(data.bh);
568     g_assert_cmpint(data.n, ==, 0);
569
570     qemu_bh_cancel(data.bh);
571     g_assert_cmpint(data.n, ==, 0);
572
573     while (g_main_context_iteration(NULL, false));
574     g_assert_cmpint(data.n, ==, 0);
575     qemu_bh_delete(data.bh);
576 }
577
578 static void test_source_bh_delete(void)
579 {
580     BHTestData data = { .n = 0 };
581     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
582
583     qemu_bh_schedule(data.bh);
584     g_assert_cmpint(data.n, ==, 0);
585
586     qemu_bh_delete(data.bh);
587     g_assert_cmpint(data.n, ==, 0);
588
589     while (g_main_context_iteration(NULL, false));
590     g_assert_cmpint(data.n, ==, 0);
591 }
592
593 static void test_source_bh_delete_from_cb(void)
594 {
595     BHTestData data1 = { .n = 0, .max = 1 };
596
597     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
598
599     qemu_bh_schedule(data1.bh);
600     g_assert_cmpint(data1.n, ==, 0);
601
602     g_main_context_iteration(NULL, true);
603     g_assert_cmpint(data1.n, ==, data1.max);
604     g_assert(data1.bh == NULL);
605
606     g_assert(!g_main_context_iteration(NULL, false));
607 }
608
609 static void test_source_bh_delete_from_cb_many(void)
610 {
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 };
615
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);
620
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);
629
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);
636
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);
646 }
647
648 static void test_source_bh_flush(void)
649 {
650     BHTestData data = { .n = 0 };
651     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
652
653     qemu_bh_schedule(data.bh);
654     g_assert_cmpint(data.n, ==, 0);
655
656     g_assert(g_main_context_iteration(NULL, true));
657     g_assert_cmpint(data.n, ==, 1);
658
659     g_assert(!g_main_context_iteration(NULL, false));
660     g_assert_cmpint(data.n, ==, 1);
661     qemu_bh_delete(data.bh);
662 }
663
664 static void test_source_set_event_notifier(void)
665 {
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);
671
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);
676 }
677
678 static void test_source_wait_event_notifier(void)
679 {
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);
686
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);
691
692     while (g_main_context_iteration(NULL, false));
693     g_assert_cmpint(data.n, ==, 1);
694     g_assert_cmpint(data.active, ==, 0);
695
696     aio_set_event_notifier(ctx, &data.e, NULL);
697     while (g_main_context_iteration(NULL, false));
698     g_assert_cmpint(data.n, ==, 1);
699
700     event_notifier_cleanup(&data.e);
701 }
702
703 static void test_source_flush_event_notifier(void)
704 {
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);
711
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));
717
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));
722
723     aio_set_event_notifier(ctx, &data.e, NULL);
724     while (g_main_context_iteration(NULL, false));
725     event_notifier_cleanup(&data.e);
726 }
727
728 static void test_source_wait_event_notifier_noflush(void)
729 {
730     EventNotifierTestData data = { .n = 0 };
731     EventNotifierTestData dummy = { .n = 0, .active = 1 };
732
733     event_notifier_init(&data.e, false);
734     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
735
736     while (g_main_context_iteration(NULL, false));
737     g_assert_cmpint(data.n, ==, 0);
738
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;
744
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);
748
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);
754
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);
760
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);
766
767     aio_set_event_notifier(ctx, &dummy.e, NULL);
768     event_notifier_cleanup(&dummy.e);
769
770     aio_set_event_notifier(ctx, &data.e, NULL);
771     while (g_main_context_iteration(NULL, false));
772     g_assert_cmpint(data.n, ==, 2);
773
774     event_notifier_cleanup(&data.e);
775 }
776
777 #if !defined(_WIN32)
778
779 static void test_source_timer_schedule(void)
780 {
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;
786
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.
789      */
790     g_assert(!qemu_pipe(pipefd));
791     qemu_set_nonblock(pipefd[0]);
792     qemu_set_nonblock(pipefd[1]);
793
794     aio_set_fd_handler(ctx, pipefd[0],
795                        dummy_io_handler_read, NULL, NULL);
796     do {} while (g_main_context_iteration(NULL, false));
797
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);
803
804     g_assert_cmpint(data.n, ==, 0);
805
806     g_usleep(1 * G_USEC_PER_SEC);
807     g_assert_cmpint(data.n, ==, 0);
808
809     g_assert(g_main_context_iteration(NULL, true));
810     g_assert_cmpint(data.n, ==, 1);
811     expiry += data.ns;
812
813     while (data.n < 2) {
814         g_main_context_iteration(NULL, true);
815     }
816
817     g_assert_cmpint(data.n, ==, 2);
818     g_assert(qemu_clock_get_ns(data.clock_type) > expiry);
819
820     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
821     close(pipefd[0]);
822     close(pipefd[1]);
823
824     timer_del(&data.timer);
825 }
826
827 #endif /* !_WIN32 */
828
829
830 /* End of tests.  */
831
832 int main(int argc, char **argv)
833 {
834     GSource *src;
835
836     init_clocks();
837
838     ctx = aio_context_new();
839     src = aio_get_g_source(ctx);
840     g_source_attach(src, NULL);
841     g_source_unref(src);
842
843     while (g_main_context_iteration(NULL, false));
844
845     g_test_init(&argc, &argv, NULL);
846     g_test_add_func("/aio/notify",                  test_notify);
847     g_test_add_func("/aio/acquire",                 test_acquire);
848     g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
849     g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
850     g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
851     g_test_add_func("/aio/bh/delete",               test_bh_delete);
852     g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
853     g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
854     g_test_add_func("/aio/bh/flush",                test_bh_flush);
855     g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
856     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
857     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
858     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
859 #if !defined(_WIN32)
860     g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
861 #endif
862
863     g_test_add_func("/aio-gsource/notify",                  test_source_notify);
864     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
865     g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
866     g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
867     g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
868     g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
869     g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
870     g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
871     g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
872     g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
873     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
874     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
875     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
876 #if !defined(_WIN32)
877     g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
878 #endif
879     return g_test_run();
880 }