]> Git Repo - qemu.git/blob - tests/test-aio.c
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
[qemu.git] / tests / test-aio.c
1 /*
2  * AioContext tests
3  *
4  * Copyright Red Hat, Inc. 2012
5  *
6  * Authors:
7  *  Paolo Bonzini    <[email protected]>
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
17 AioContext *ctx;
18
19 typedef struct {
20     EventNotifier e;
21     int n;
22     int active;
23     bool auto_set;
24 } EventNotifierTestData;
25
26 /* Wait until there are no more BHs or AIO requests */
27 static void wait_for_aio(void)
28 {
29     while (aio_poll(ctx, true)) {
30         /* Do nothing */
31     }
32 }
33
34 /* Wait until event notifier becomes inactive */
35 static void wait_until_inactive(EventNotifierTestData *data)
36 {
37     while (data->active > 0) {
38         aio_poll(ctx, true);
39     }
40 }
41
42 /* Simple callbacks for testing.  */
43
44 typedef struct {
45     QEMUBH *bh;
46     int n;
47     int max;
48 } BHTestData;
49
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;
58
59 static void bh_test_cb(void *opaque)
60 {
61     BHTestData *data = opaque;
62     if (++data->n < data->max) {
63         qemu_bh_schedule(data->bh);
64     }
65 }
66
67 static void timer_test_cb(void *opaque)
68 {
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);
73     }
74 }
75
76 static void dummy_io_handler_read(void *opaque)
77 {
78 }
79
80 static void bh_delete_cb(void *opaque)
81 {
82     BHTestData *data = opaque;
83     if (++data->n < data->max) {
84         qemu_bh_schedule(data->bh);
85     } else {
86         qemu_bh_delete(data->bh);
87         data->bh = NULL;
88     }
89 }
90
91 static void event_ready_cb(EventNotifier *e)
92 {
93     EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
94     g_assert(event_notifier_test_and_clear(e));
95     data->n++;
96     if (data->active > 0) {
97         data->active--;
98     }
99     if (data->auto_set && data->active) {
100         event_notifier_set(e);
101     }
102 }
103
104 /* Tests using aio_*.  */
105
106 static void test_notify(void)
107 {
108     g_assert(!aio_poll(ctx, false));
109     aio_notify(ctx);
110     g_assert(!aio_poll(ctx, true));
111     g_assert(!aio_poll(ctx, false));
112 }
113
114 static void test_bh_schedule(void)
115 {
116     BHTestData data = { .n = 0 };
117     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
118
119     qemu_bh_schedule(data.bh);
120     g_assert_cmpint(data.n, ==, 0);
121
122     g_assert(aio_poll(ctx, true));
123     g_assert_cmpint(data.n, ==, 1);
124
125     g_assert(!aio_poll(ctx, false));
126     g_assert_cmpint(data.n, ==, 1);
127     qemu_bh_delete(data.bh);
128 }
129
130 static void test_bh_schedule10(void)
131 {
132     BHTestData data = { .n = 0, .max = 10 };
133     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
134
135     qemu_bh_schedule(data.bh);
136     g_assert_cmpint(data.n, ==, 0);
137
138     g_assert(aio_poll(ctx, false));
139     g_assert_cmpint(data.n, ==, 1);
140
141     g_assert(aio_poll(ctx, true));
142     g_assert_cmpint(data.n, ==, 2);
143
144     wait_for_aio();
145     g_assert_cmpint(data.n, ==, 10);
146
147     g_assert(!aio_poll(ctx, false));
148     g_assert_cmpint(data.n, ==, 10);
149     qemu_bh_delete(data.bh);
150 }
151
152 static void test_bh_cancel(void)
153 {
154     BHTestData data = { .n = 0 };
155     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
156
157     qemu_bh_schedule(data.bh);
158     g_assert_cmpint(data.n, ==, 0);
159
160     qemu_bh_cancel(data.bh);
161     g_assert_cmpint(data.n, ==, 0);
162
163     g_assert(!aio_poll(ctx, false));
164     g_assert_cmpint(data.n, ==, 0);
165     qemu_bh_delete(data.bh);
166 }
167
168 static void test_bh_delete(void)
169 {
170     BHTestData data = { .n = 0 };
171     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
172
173     qemu_bh_schedule(data.bh);
174     g_assert_cmpint(data.n, ==, 0);
175
176     qemu_bh_delete(data.bh);
177     g_assert_cmpint(data.n, ==, 0);
178
179     g_assert(!aio_poll(ctx, false));
180     g_assert_cmpint(data.n, ==, 0);
181 }
182
183 static void test_bh_delete_from_cb(void)
184 {
185     BHTestData data1 = { .n = 0, .max = 1 };
186
187     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
188
189     qemu_bh_schedule(data1.bh);
190     g_assert_cmpint(data1.n, ==, 0);
191
192     wait_for_aio();
193     g_assert_cmpint(data1.n, ==, data1.max);
194     g_assert(data1.bh == NULL);
195
196     g_assert(!aio_poll(ctx, false));
197     g_assert(!aio_poll(ctx, true));
198 }
199
200 static void test_bh_delete_from_cb_many(void)
201 {
202     BHTestData data1 = { .n = 0, .max = 1 };
203     BHTestData data2 = { .n = 0, .max = 3 };
204     BHTestData data3 = { .n = 0, .max = 2 };
205     BHTestData data4 = { .n = 0, .max = 4 };
206
207     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
208     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
209     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
210     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
211
212     qemu_bh_schedule(data1.bh);
213     qemu_bh_schedule(data2.bh);
214     qemu_bh_schedule(data3.bh);
215     qemu_bh_schedule(data4.bh);
216     g_assert_cmpint(data1.n, ==, 0);
217     g_assert_cmpint(data2.n, ==, 0);
218     g_assert_cmpint(data3.n, ==, 0);
219     g_assert_cmpint(data4.n, ==, 0);
220
221     g_assert(aio_poll(ctx, false));
222     g_assert_cmpint(data1.n, ==, 1);
223     g_assert_cmpint(data2.n, ==, 1);
224     g_assert_cmpint(data3.n, ==, 1);
225     g_assert_cmpint(data4.n, ==, 1);
226     g_assert(data1.bh == NULL);
227
228     wait_for_aio();
229     g_assert_cmpint(data1.n, ==, data1.max);
230     g_assert_cmpint(data2.n, ==, data2.max);
231     g_assert_cmpint(data3.n, ==, data3.max);
232     g_assert_cmpint(data4.n, ==, data4.max);
233     g_assert(data1.bh == NULL);
234     g_assert(data2.bh == NULL);
235     g_assert(data3.bh == NULL);
236     g_assert(data4.bh == NULL);
237 }
238
239 static void test_bh_flush(void)
240 {
241     BHTestData data = { .n = 0 };
242     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
243
244     qemu_bh_schedule(data.bh);
245     g_assert_cmpint(data.n, ==, 0);
246
247     wait_for_aio();
248     g_assert_cmpint(data.n, ==, 1);
249
250     g_assert(!aio_poll(ctx, false));
251     g_assert_cmpint(data.n, ==, 1);
252     qemu_bh_delete(data.bh);
253 }
254
255 static void test_set_event_notifier(void)
256 {
257     EventNotifierTestData data = { .n = 0, .active = 0 };
258     event_notifier_init(&data.e, false);
259     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
260     g_assert(!aio_poll(ctx, false));
261     g_assert_cmpint(data.n, ==, 0);
262
263     aio_set_event_notifier(ctx, &data.e, NULL);
264     g_assert(!aio_poll(ctx, false));
265     g_assert_cmpint(data.n, ==, 0);
266     event_notifier_cleanup(&data.e);
267 }
268
269 static void test_wait_event_notifier(void)
270 {
271     EventNotifierTestData data = { .n = 0, .active = 1 };
272     event_notifier_init(&data.e, false);
273     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
274     g_assert(!aio_poll(ctx, false));
275     g_assert_cmpint(data.n, ==, 0);
276     g_assert_cmpint(data.active, ==, 1);
277
278     event_notifier_set(&data.e);
279     g_assert(aio_poll(ctx, false));
280     g_assert_cmpint(data.n, ==, 1);
281     g_assert_cmpint(data.active, ==, 0);
282
283     g_assert(!aio_poll(ctx, false));
284     g_assert_cmpint(data.n, ==, 1);
285     g_assert_cmpint(data.active, ==, 0);
286
287     aio_set_event_notifier(ctx, &data.e, NULL);
288     g_assert(!aio_poll(ctx, false));
289     g_assert_cmpint(data.n, ==, 1);
290
291     event_notifier_cleanup(&data.e);
292 }
293
294 static void test_flush_event_notifier(void)
295 {
296     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
297     event_notifier_init(&data.e, false);
298     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
299     g_assert(!aio_poll(ctx, false));
300     g_assert_cmpint(data.n, ==, 0);
301     g_assert_cmpint(data.active, ==, 10);
302
303     event_notifier_set(&data.e);
304     g_assert(aio_poll(ctx, false));
305     g_assert_cmpint(data.n, ==, 1);
306     g_assert_cmpint(data.active, ==, 9);
307     g_assert(aio_poll(ctx, false));
308
309     wait_until_inactive(&data);
310     g_assert_cmpint(data.n, ==, 10);
311     g_assert_cmpint(data.active, ==, 0);
312     g_assert(!aio_poll(ctx, false));
313
314     aio_set_event_notifier(ctx, &data.e, NULL);
315     g_assert(!aio_poll(ctx, false));
316     event_notifier_cleanup(&data.e);
317 }
318
319 static void test_wait_event_notifier_noflush(void)
320 {
321     EventNotifierTestData data = { .n = 0 };
322     EventNotifierTestData dummy = { .n = 0, .active = 1 };
323
324     event_notifier_init(&data.e, false);
325     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
326
327     g_assert(!aio_poll(ctx, false));
328     g_assert_cmpint(data.n, ==, 0);
329
330     /* Until there is an active descriptor, aio_poll may or may not call
331      * event_ready_cb.  Still, it must not block.  */
332     event_notifier_set(&data.e);
333     g_assert(aio_poll(ctx, true));
334     data.n = 0;
335
336     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
337     event_notifier_init(&dummy.e, false);
338     aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
339
340     event_notifier_set(&data.e);
341     g_assert(aio_poll(ctx, false));
342     g_assert_cmpint(data.n, ==, 1);
343     g_assert(!aio_poll(ctx, false));
344     g_assert_cmpint(data.n, ==, 1);
345
346     event_notifier_set(&data.e);
347     g_assert(aio_poll(ctx, false));
348     g_assert_cmpint(data.n, ==, 2);
349     g_assert(!aio_poll(ctx, false));
350     g_assert_cmpint(data.n, ==, 2);
351
352     event_notifier_set(&dummy.e);
353     wait_until_inactive(&dummy);
354     g_assert_cmpint(data.n, ==, 2);
355     g_assert_cmpint(dummy.n, ==, 1);
356     g_assert_cmpint(dummy.active, ==, 0);
357
358     aio_set_event_notifier(ctx, &dummy.e, NULL);
359     event_notifier_cleanup(&dummy.e);
360
361     aio_set_event_notifier(ctx, &data.e, NULL);
362     g_assert(!aio_poll(ctx, false));
363     g_assert_cmpint(data.n, ==, 2);
364
365     event_notifier_cleanup(&data.e);
366 }
367
368 static void test_timer_schedule(void)
369 {
370     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
371                            .max = 2,
372                            .clock_type = QEMU_CLOCK_VIRTUAL };
373     int pipefd[2];
374
375     /* aio_poll will not block to wait for timers to complete unless it has
376      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
377      */
378     g_assert(!pipe2(pipefd, O_NONBLOCK));
379     aio_set_fd_handler(ctx, pipefd[0],
380                        dummy_io_handler_read, NULL, NULL);
381     aio_poll(ctx, false);
382
383     aio_timer_init(ctx, &data.timer, data.clock_type,
384                    SCALE_NS, timer_test_cb, &data);
385     timer_mod(&data.timer,
386               qemu_clock_get_ns(data.clock_type) +
387               data.ns);
388
389     g_assert_cmpint(data.n, ==, 0);
390
391     /* timer_mod may well cause an event notifer to have gone off,
392      * so clear that
393      */
394     do {} while (aio_poll(ctx, false));
395
396     g_assert(!aio_poll(ctx, false));
397     g_assert_cmpint(data.n, ==, 0);
398
399     sleep(1);
400     g_assert_cmpint(data.n, ==, 0);
401
402     g_assert(aio_poll(ctx, false));
403     g_assert_cmpint(data.n, ==, 1);
404
405     /* timer_mod called by our callback */
406     do {} while (aio_poll(ctx, false));
407
408     g_assert(!aio_poll(ctx, false));
409     g_assert_cmpint(data.n, ==, 1);
410
411     g_assert(aio_poll(ctx, true));
412     g_assert_cmpint(data.n, ==, 2);
413
414     /* As max is now 2, an event notifier should not have gone off */
415
416     g_assert(!aio_poll(ctx, false));
417     g_assert_cmpint(data.n, ==, 2);
418
419     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
420     close(pipefd[0]);
421     close(pipefd[1]);
422
423     timer_del(&data.timer);
424 }
425
426 /* Now the same tests, using the context as a GSource.  They are
427  * very similar to the ones above, with g_main_context_iteration
428  * replacing aio_poll.  However:
429  * - sometimes both the AioContext and the glib main loop wake
430  *   themselves up.  Hence, some "g_assert(!aio_poll(ctx, false));"
431  *   are replaced by "while (g_main_context_iteration(NULL, false));".
432  * - there is no exact replacement for a blocking wait.
433  *   "while (g_main_context_iteration(NULL, true)" seems to work,
434  *   but it is not documented _why_ it works.  For these tests a
435  *   non-blocking loop like "while (g_main_context_iteration(NULL, false)"
436  *   works well, and that's what I am using.
437  */
438
439 static void test_source_notify(void)
440 {
441     while (g_main_context_iteration(NULL, false));
442     aio_notify(ctx);
443     g_assert(g_main_context_iteration(NULL, true));
444     g_assert(!g_main_context_iteration(NULL, false));
445 }
446
447 static void test_source_flush(void)
448 {
449     g_assert(!g_main_context_iteration(NULL, false));
450     aio_notify(ctx);
451     while (g_main_context_iteration(NULL, false));
452     g_assert(!g_main_context_iteration(NULL, false));
453 }
454
455 static void test_source_bh_schedule(void)
456 {
457     BHTestData data = { .n = 0 };
458     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
459
460     qemu_bh_schedule(data.bh);
461     g_assert_cmpint(data.n, ==, 0);
462
463     g_assert(g_main_context_iteration(NULL, true));
464     g_assert_cmpint(data.n, ==, 1);
465
466     g_assert(!g_main_context_iteration(NULL, false));
467     g_assert_cmpint(data.n, ==, 1);
468     qemu_bh_delete(data.bh);
469 }
470
471 static void test_source_bh_schedule10(void)
472 {
473     BHTestData data = { .n = 0, .max = 10 };
474     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
475
476     qemu_bh_schedule(data.bh);
477     g_assert_cmpint(data.n, ==, 0);
478
479     g_assert(g_main_context_iteration(NULL, false));
480     g_assert_cmpint(data.n, ==, 1);
481
482     g_assert(g_main_context_iteration(NULL, true));
483     g_assert_cmpint(data.n, ==, 2);
484
485     while (g_main_context_iteration(NULL, false));
486     g_assert_cmpint(data.n, ==, 10);
487
488     g_assert(!g_main_context_iteration(NULL, false));
489     g_assert_cmpint(data.n, ==, 10);
490     qemu_bh_delete(data.bh);
491 }
492
493 static void test_source_bh_cancel(void)
494 {
495     BHTestData data = { .n = 0 };
496     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
497
498     qemu_bh_schedule(data.bh);
499     g_assert_cmpint(data.n, ==, 0);
500
501     qemu_bh_cancel(data.bh);
502     g_assert_cmpint(data.n, ==, 0);
503
504     while (g_main_context_iteration(NULL, false));
505     g_assert_cmpint(data.n, ==, 0);
506     qemu_bh_delete(data.bh);
507 }
508
509 static void test_source_bh_delete(void)
510 {
511     BHTestData data = { .n = 0 };
512     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
513
514     qemu_bh_schedule(data.bh);
515     g_assert_cmpint(data.n, ==, 0);
516
517     qemu_bh_delete(data.bh);
518     g_assert_cmpint(data.n, ==, 0);
519
520     while (g_main_context_iteration(NULL, false));
521     g_assert_cmpint(data.n, ==, 0);
522 }
523
524 static void test_source_bh_delete_from_cb(void)
525 {
526     BHTestData data1 = { .n = 0, .max = 1 };
527
528     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
529
530     qemu_bh_schedule(data1.bh);
531     g_assert_cmpint(data1.n, ==, 0);
532
533     g_main_context_iteration(NULL, true);
534     g_assert_cmpint(data1.n, ==, data1.max);
535     g_assert(data1.bh == NULL);
536
537     g_assert(!g_main_context_iteration(NULL, false));
538 }
539
540 static void test_source_bh_delete_from_cb_many(void)
541 {
542     BHTestData data1 = { .n = 0, .max = 1 };
543     BHTestData data2 = { .n = 0, .max = 3 };
544     BHTestData data3 = { .n = 0, .max = 2 };
545     BHTestData data4 = { .n = 0, .max = 4 };
546
547     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
548     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
549     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
550     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
551
552     qemu_bh_schedule(data1.bh);
553     qemu_bh_schedule(data2.bh);
554     qemu_bh_schedule(data3.bh);
555     qemu_bh_schedule(data4.bh);
556     g_assert_cmpint(data1.n, ==, 0);
557     g_assert_cmpint(data2.n, ==, 0);
558     g_assert_cmpint(data3.n, ==, 0);
559     g_assert_cmpint(data4.n, ==, 0);
560
561     g_assert(g_main_context_iteration(NULL, false));
562     g_assert_cmpint(data1.n, ==, 1);
563     g_assert_cmpint(data2.n, ==, 1);
564     g_assert_cmpint(data3.n, ==, 1);
565     g_assert_cmpint(data4.n, ==, 1);
566     g_assert(data1.bh == NULL);
567
568     while (g_main_context_iteration(NULL, false));
569     g_assert_cmpint(data1.n, ==, data1.max);
570     g_assert_cmpint(data2.n, ==, data2.max);
571     g_assert_cmpint(data3.n, ==, data3.max);
572     g_assert_cmpint(data4.n, ==, data4.max);
573     g_assert(data1.bh == NULL);
574     g_assert(data2.bh == NULL);
575     g_assert(data3.bh == NULL);
576     g_assert(data4.bh == NULL);
577 }
578
579 static void test_source_bh_flush(void)
580 {
581     BHTestData data = { .n = 0 };
582     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
583
584     qemu_bh_schedule(data.bh);
585     g_assert_cmpint(data.n, ==, 0);
586
587     g_assert(g_main_context_iteration(NULL, true));
588     g_assert_cmpint(data.n, ==, 1);
589
590     g_assert(!g_main_context_iteration(NULL, false));
591     g_assert_cmpint(data.n, ==, 1);
592     qemu_bh_delete(data.bh);
593 }
594
595 static void test_source_set_event_notifier(void)
596 {
597     EventNotifierTestData data = { .n = 0, .active = 0 };
598     event_notifier_init(&data.e, false);
599     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
600     while (g_main_context_iteration(NULL, false));
601     g_assert_cmpint(data.n, ==, 0);
602
603     aio_set_event_notifier(ctx, &data.e, NULL);
604     while (g_main_context_iteration(NULL, false));
605     g_assert_cmpint(data.n, ==, 0);
606     event_notifier_cleanup(&data.e);
607 }
608
609 static void test_source_wait_event_notifier(void)
610 {
611     EventNotifierTestData data = { .n = 0, .active = 1 };
612     event_notifier_init(&data.e, false);
613     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
614     g_assert(g_main_context_iteration(NULL, false));
615     g_assert_cmpint(data.n, ==, 0);
616     g_assert_cmpint(data.active, ==, 1);
617
618     event_notifier_set(&data.e);
619     g_assert(g_main_context_iteration(NULL, false));
620     g_assert_cmpint(data.n, ==, 1);
621     g_assert_cmpint(data.active, ==, 0);
622
623     while (g_main_context_iteration(NULL, false));
624     g_assert_cmpint(data.n, ==, 1);
625     g_assert_cmpint(data.active, ==, 0);
626
627     aio_set_event_notifier(ctx, &data.e, NULL);
628     while (g_main_context_iteration(NULL, false));
629     g_assert_cmpint(data.n, ==, 1);
630
631     event_notifier_cleanup(&data.e);
632 }
633
634 static void test_source_flush_event_notifier(void)
635 {
636     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
637     event_notifier_init(&data.e, false);
638     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
639     g_assert(g_main_context_iteration(NULL, false));
640     g_assert_cmpint(data.n, ==, 0);
641     g_assert_cmpint(data.active, ==, 10);
642
643     event_notifier_set(&data.e);
644     g_assert(g_main_context_iteration(NULL, false));
645     g_assert_cmpint(data.n, ==, 1);
646     g_assert_cmpint(data.active, ==, 9);
647     g_assert(g_main_context_iteration(NULL, false));
648
649     while (g_main_context_iteration(NULL, false));
650     g_assert_cmpint(data.n, ==, 10);
651     g_assert_cmpint(data.active, ==, 0);
652     g_assert(!g_main_context_iteration(NULL, false));
653
654     aio_set_event_notifier(ctx, &data.e, NULL);
655     while (g_main_context_iteration(NULL, false));
656     event_notifier_cleanup(&data.e);
657 }
658
659 static void test_source_wait_event_notifier_noflush(void)
660 {
661     EventNotifierTestData data = { .n = 0 };
662     EventNotifierTestData dummy = { .n = 0, .active = 1 };
663
664     event_notifier_init(&data.e, false);
665     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
666
667     while (g_main_context_iteration(NULL, false));
668     g_assert_cmpint(data.n, ==, 0);
669
670     /* Until there is an active descriptor, glib may or may not call
671      * event_ready_cb.  Still, it must not block.  */
672     event_notifier_set(&data.e);
673     g_main_context_iteration(NULL, true);
674     data.n = 0;
675
676     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
677     event_notifier_init(&dummy.e, false);
678     aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
679
680     event_notifier_set(&data.e);
681     g_assert(g_main_context_iteration(NULL, false));
682     g_assert_cmpint(data.n, ==, 1);
683     g_assert(!g_main_context_iteration(NULL, false));
684     g_assert_cmpint(data.n, ==, 1);
685
686     event_notifier_set(&data.e);
687     g_assert(g_main_context_iteration(NULL, false));
688     g_assert_cmpint(data.n, ==, 2);
689     g_assert(!g_main_context_iteration(NULL, false));
690     g_assert_cmpint(data.n, ==, 2);
691
692     event_notifier_set(&dummy.e);
693     while (g_main_context_iteration(NULL, false));
694     g_assert_cmpint(data.n, ==, 2);
695     g_assert_cmpint(dummy.n, ==, 1);
696     g_assert_cmpint(dummy.active, ==, 0);
697
698     aio_set_event_notifier(ctx, &dummy.e, NULL);
699     event_notifier_cleanup(&dummy.e);
700
701     aio_set_event_notifier(ctx, &data.e, NULL);
702     while (g_main_context_iteration(NULL, false));
703     g_assert_cmpint(data.n, ==, 2);
704
705     event_notifier_cleanup(&data.e);
706 }
707
708 static void test_source_timer_schedule(void)
709 {
710     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
711                            .max = 2,
712                            .clock_type = QEMU_CLOCK_VIRTUAL };
713     int pipefd[2];
714     int64_t expiry;
715
716     /* aio_poll will not block to wait for timers to complete unless it has
717      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
718      */
719     g_assert(!pipe2(pipefd, O_NONBLOCK));
720     aio_set_fd_handler(ctx, pipefd[0],
721                        dummy_io_handler_read, NULL, NULL);
722     do {} while (g_main_context_iteration(NULL, false));
723
724     aio_timer_init(ctx, &data.timer, data.clock_type,
725                    SCALE_NS, timer_test_cb, &data);
726     expiry = qemu_clock_get_ns(data.clock_type) +
727         data.ns;
728     timer_mod(&data.timer, expiry);
729
730     g_assert_cmpint(data.n, ==, 0);
731
732     sleep(1);
733     g_assert_cmpint(data.n, ==, 0);
734
735     g_assert(g_main_context_iteration(NULL, false));
736     g_assert_cmpint(data.n, ==, 1);
737
738     /* The comment above was not kidding when it said this wakes up itself */
739     do {
740         g_assert(g_main_context_iteration(NULL, true));
741     } while (qemu_clock_get_ns(data.clock_type) <= expiry);
742     sleep(1);
743     g_main_context_iteration(NULL, false);
744
745     g_assert_cmpint(data.n, ==, 2);
746
747     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
748     close(pipefd[0]);
749     close(pipefd[1]);
750
751     timer_del(&data.timer);
752 }
753
754
755 /* End of tests.  */
756
757 int main(int argc, char **argv)
758 {
759     GSource *src;
760
761     init_clocks();
762
763     ctx = aio_context_new();
764     src = aio_get_g_source(ctx);
765     g_source_attach(src, NULL);
766     g_source_unref(src);
767
768     while (g_main_context_iteration(NULL, false));
769
770     g_test_init(&argc, &argv, NULL);
771     g_test_add_func("/aio/notify",                  test_notify);
772     g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
773     g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
774     g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
775     g_test_add_func("/aio/bh/delete",               test_bh_delete);
776     g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
777     g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
778     g_test_add_func("/aio/bh/flush",                test_bh_flush);
779     g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
780     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
781     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
782     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
783     g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
784
785     g_test_add_func("/aio-gsource/notify",                  test_source_notify);
786     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
787     g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
788     g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
789     g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
790     g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
791     g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
792     g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
793     g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
794     g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
795     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
796     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
797     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
798     g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
799     return g_test_run();
800 }
This page took 0.068352 seconds and 4 git commands to generate.