]> Git Repo - qemu.git/blob - tests/test-aio.c
tests/qapi-schema: Cover union types with base
[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 #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 static void timer_test_cb(void *opaque)
69 {
70     TimerTestData *data = opaque;
71     if (++data->n < data->max) {
72         timer_mod(&data->timer,
73                   qemu_clock_get_ns(data->clock_type) + data->ns);
74     }
75 }
76
77 static void dummy_io_handler_read(void *opaque)
78 {
79 }
80
81 static void bh_delete_cb(void *opaque)
82 {
83     BHTestData *data = opaque;
84     if (++data->n < data->max) {
85         qemu_bh_schedule(data->bh);
86     } else {
87         qemu_bh_delete(data->bh);
88         data->bh = NULL;
89     }
90 }
91
92 static void event_ready_cb(EventNotifier *e)
93 {
94     EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
95     g_assert(event_notifier_test_and_clear(e));
96     data->n++;
97     if (data->active > 0) {
98         data->active--;
99     }
100     if (data->auto_set && data->active) {
101         event_notifier_set(e);
102     }
103 }
104
105 /* Tests using aio_*.  */
106
107 static void test_notify(void)
108 {
109     g_assert(!aio_poll(ctx, false));
110     aio_notify(ctx);
111     g_assert(!aio_poll(ctx, true));
112     g_assert(!aio_poll(ctx, false));
113 }
114
115 static void test_bh_schedule(void)
116 {
117     BHTestData data = { .n = 0 };
118     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
119
120     qemu_bh_schedule(data.bh);
121     g_assert_cmpint(data.n, ==, 0);
122
123     g_assert(aio_poll(ctx, true));
124     g_assert_cmpint(data.n, ==, 1);
125
126     g_assert(!aio_poll(ctx, false));
127     g_assert_cmpint(data.n, ==, 1);
128     qemu_bh_delete(data.bh);
129 }
130
131 static void test_bh_schedule10(void)
132 {
133     BHTestData data = { .n = 0, .max = 10 };
134     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
135
136     qemu_bh_schedule(data.bh);
137     g_assert_cmpint(data.n, ==, 0);
138
139     g_assert(aio_poll(ctx, false));
140     g_assert_cmpint(data.n, ==, 1);
141
142     g_assert(aio_poll(ctx, true));
143     g_assert_cmpint(data.n, ==, 2);
144
145     wait_for_aio();
146     g_assert_cmpint(data.n, ==, 10);
147
148     g_assert(!aio_poll(ctx, false));
149     g_assert_cmpint(data.n, ==, 10);
150     qemu_bh_delete(data.bh);
151 }
152
153 static void test_bh_cancel(void)
154 {
155     BHTestData data = { .n = 0 };
156     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
157
158     qemu_bh_schedule(data.bh);
159     g_assert_cmpint(data.n, ==, 0);
160
161     qemu_bh_cancel(data.bh);
162     g_assert_cmpint(data.n, ==, 0);
163
164     g_assert(!aio_poll(ctx, false));
165     g_assert_cmpint(data.n, ==, 0);
166     qemu_bh_delete(data.bh);
167 }
168
169 static void test_bh_delete(void)
170 {
171     BHTestData data = { .n = 0 };
172     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
173
174     qemu_bh_schedule(data.bh);
175     g_assert_cmpint(data.n, ==, 0);
176
177     qemu_bh_delete(data.bh);
178     g_assert_cmpint(data.n, ==, 0);
179
180     g_assert(!aio_poll(ctx, false));
181     g_assert_cmpint(data.n, ==, 0);
182 }
183
184 static void test_bh_delete_from_cb(void)
185 {
186     BHTestData data1 = { .n = 0, .max = 1 };
187
188     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
189
190     qemu_bh_schedule(data1.bh);
191     g_assert_cmpint(data1.n, ==, 0);
192
193     wait_for_aio();
194     g_assert_cmpint(data1.n, ==, data1.max);
195     g_assert(data1.bh == NULL);
196
197     g_assert(!aio_poll(ctx, false));
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(!qemu_pipe(pipefd));
379     qemu_set_nonblock(pipefd[0]);
380     qemu_set_nonblock(pipefd[1]);
381
382     aio_set_fd_handler(ctx, pipefd[0],
383                        dummy_io_handler_read, NULL, NULL);
384     aio_poll(ctx, false);
385
386     aio_timer_init(ctx, &data.timer, data.clock_type,
387                    SCALE_NS, timer_test_cb, &data);
388     timer_mod(&data.timer,
389               qemu_clock_get_ns(data.clock_type) +
390               data.ns);
391
392     g_assert_cmpint(data.n, ==, 0);
393
394     /* timer_mod may well cause an event notifer to have gone off,
395      * so clear that
396      */
397     do {} while (aio_poll(ctx, false));
398
399     g_assert(!aio_poll(ctx, false));
400     g_assert_cmpint(data.n, ==, 0);
401
402     g_usleep(1 * G_USEC_PER_SEC);
403     g_assert_cmpint(data.n, ==, 0);
404
405     g_assert(aio_poll(ctx, false));
406     g_assert_cmpint(data.n, ==, 1);
407
408     /* timer_mod called by our callback */
409     do {} while (aio_poll(ctx, false));
410
411     g_assert(!aio_poll(ctx, false));
412     g_assert_cmpint(data.n, ==, 1);
413
414     g_assert(aio_poll(ctx, true));
415     g_assert_cmpint(data.n, ==, 2);
416
417     /* As max is now 2, an event notifier should not have gone off */
418
419     g_assert(!aio_poll(ctx, false));
420     g_assert_cmpint(data.n, ==, 2);
421
422     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
423     close(pipefd[0]);
424     close(pipefd[1]);
425
426     timer_del(&data.timer);
427 }
428
429 /* Now the same tests, using the context as a GSource.  They are
430  * very similar to the ones above, with g_main_context_iteration
431  * replacing aio_poll.  However:
432  * - sometimes both the AioContext and the glib main loop wake
433  *   themselves up.  Hence, some "g_assert(!aio_poll(ctx, false));"
434  *   are replaced by "while (g_main_context_iteration(NULL, false));".
435  * - there is no exact replacement for a blocking wait.
436  *   "while (g_main_context_iteration(NULL, true)" seems to work,
437  *   but it is not documented _why_ it works.  For these tests a
438  *   non-blocking loop like "while (g_main_context_iteration(NULL, false)"
439  *   works well, and that's what I am using.
440  */
441
442 static void test_source_notify(void)
443 {
444     while (g_main_context_iteration(NULL, false));
445     aio_notify(ctx);
446     g_assert(g_main_context_iteration(NULL, true));
447     g_assert(!g_main_context_iteration(NULL, false));
448 }
449
450 static void test_source_flush(void)
451 {
452     g_assert(!g_main_context_iteration(NULL, false));
453     aio_notify(ctx);
454     while (g_main_context_iteration(NULL, false));
455     g_assert(!g_main_context_iteration(NULL, false));
456 }
457
458 static void test_source_bh_schedule(void)
459 {
460     BHTestData data = { .n = 0 };
461     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
462
463     qemu_bh_schedule(data.bh);
464     g_assert_cmpint(data.n, ==, 0);
465
466     g_assert(g_main_context_iteration(NULL, true));
467     g_assert_cmpint(data.n, ==, 1);
468
469     g_assert(!g_main_context_iteration(NULL, false));
470     g_assert_cmpint(data.n, ==, 1);
471     qemu_bh_delete(data.bh);
472 }
473
474 static void test_source_bh_schedule10(void)
475 {
476     BHTestData data = { .n = 0, .max = 10 };
477     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
478
479     qemu_bh_schedule(data.bh);
480     g_assert_cmpint(data.n, ==, 0);
481
482     g_assert(g_main_context_iteration(NULL, false));
483     g_assert_cmpint(data.n, ==, 1);
484
485     g_assert(g_main_context_iteration(NULL, true));
486     g_assert_cmpint(data.n, ==, 2);
487
488     while (g_main_context_iteration(NULL, false));
489     g_assert_cmpint(data.n, ==, 10);
490
491     g_assert(!g_main_context_iteration(NULL, false));
492     g_assert_cmpint(data.n, ==, 10);
493     qemu_bh_delete(data.bh);
494 }
495
496 static void test_source_bh_cancel(void)
497 {
498     BHTestData data = { .n = 0 };
499     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
500
501     qemu_bh_schedule(data.bh);
502     g_assert_cmpint(data.n, ==, 0);
503
504     qemu_bh_cancel(data.bh);
505     g_assert_cmpint(data.n, ==, 0);
506
507     while (g_main_context_iteration(NULL, false));
508     g_assert_cmpint(data.n, ==, 0);
509     qemu_bh_delete(data.bh);
510 }
511
512 static void test_source_bh_delete(void)
513 {
514     BHTestData data = { .n = 0 };
515     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
516
517     qemu_bh_schedule(data.bh);
518     g_assert_cmpint(data.n, ==, 0);
519
520     qemu_bh_delete(data.bh);
521     g_assert_cmpint(data.n, ==, 0);
522
523     while (g_main_context_iteration(NULL, false));
524     g_assert_cmpint(data.n, ==, 0);
525 }
526
527 static void test_source_bh_delete_from_cb(void)
528 {
529     BHTestData data1 = { .n = 0, .max = 1 };
530
531     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
532
533     qemu_bh_schedule(data1.bh);
534     g_assert_cmpint(data1.n, ==, 0);
535
536     g_main_context_iteration(NULL, true);
537     g_assert_cmpint(data1.n, ==, data1.max);
538     g_assert(data1.bh == NULL);
539
540     g_assert(!g_main_context_iteration(NULL, false));
541 }
542
543 static void test_source_bh_delete_from_cb_many(void)
544 {
545     BHTestData data1 = { .n = 0, .max = 1 };
546     BHTestData data2 = { .n = 0, .max = 3 };
547     BHTestData data3 = { .n = 0, .max = 2 };
548     BHTestData data4 = { .n = 0, .max = 4 };
549
550     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
551     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
552     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
553     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
554
555     qemu_bh_schedule(data1.bh);
556     qemu_bh_schedule(data2.bh);
557     qemu_bh_schedule(data3.bh);
558     qemu_bh_schedule(data4.bh);
559     g_assert_cmpint(data1.n, ==, 0);
560     g_assert_cmpint(data2.n, ==, 0);
561     g_assert_cmpint(data3.n, ==, 0);
562     g_assert_cmpint(data4.n, ==, 0);
563
564     g_assert(g_main_context_iteration(NULL, false));
565     g_assert_cmpint(data1.n, ==, 1);
566     g_assert_cmpint(data2.n, ==, 1);
567     g_assert_cmpint(data3.n, ==, 1);
568     g_assert_cmpint(data4.n, ==, 1);
569     g_assert(data1.bh == NULL);
570
571     while (g_main_context_iteration(NULL, false));
572     g_assert_cmpint(data1.n, ==, data1.max);
573     g_assert_cmpint(data2.n, ==, data2.max);
574     g_assert_cmpint(data3.n, ==, data3.max);
575     g_assert_cmpint(data4.n, ==, data4.max);
576     g_assert(data1.bh == NULL);
577     g_assert(data2.bh == NULL);
578     g_assert(data3.bh == NULL);
579     g_assert(data4.bh == NULL);
580 }
581
582 static void test_source_bh_flush(void)
583 {
584     BHTestData data = { .n = 0 };
585     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
586
587     qemu_bh_schedule(data.bh);
588     g_assert_cmpint(data.n, ==, 0);
589
590     g_assert(g_main_context_iteration(NULL, true));
591     g_assert_cmpint(data.n, ==, 1);
592
593     g_assert(!g_main_context_iteration(NULL, false));
594     g_assert_cmpint(data.n, ==, 1);
595     qemu_bh_delete(data.bh);
596 }
597
598 static void test_source_set_event_notifier(void)
599 {
600     EventNotifierTestData data = { .n = 0, .active = 0 };
601     event_notifier_init(&data.e, false);
602     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
603     while (g_main_context_iteration(NULL, false));
604     g_assert_cmpint(data.n, ==, 0);
605
606     aio_set_event_notifier(ctx, &data.e, NULL);
607     while (g_main_context_iteration(NULL, false));
608     g_assert_cmpint(data.n, ==, 0);
609     event_notifier_cleanup(&data.e);
610 }
611
612 static void test_source_wait_event_notifier(void)
613 {
614     EventNotifierTestData data = { .n = 0, .active = 1 };
615     event_notifier_init(&data.e, false);
616     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
617     g_assert(g_main_context_iteration(NULL, false));
618     g_assert_cmpint(data.n, ==, 0);
619     g_assert_cmpint(data.active, ==, 1);
620
621     event_notifier_set(&data.e);
622     g_assert(g_main_context_iteration(NULL, false));
623     g_assert_cmpint(data.n, ==, 1);
624     g_assert_cmpint(data.active, ==, 0);
625
626     while (g_main_context_iteration(NULL, false));
627     g_assert_cmpint(data.n, ==, 1);
628     g_assert_cmpint(data.active, ==, 0);
629
630     aio_set_event_notifier(ctx, &data.e, NULL);
631     while (g_main_context_iteration(NULL, false));
632     g_assert_cmpint(data.n, ==, 1);
633
634     event_notifier_cleanup(&data.e);
635 }
636
637 static void test_source_flush_event_notifier(void)
638 {
639     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
640     event_notifier_init(&data.e, false);
641     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
642     g_assert(g_main_context_iteration(NULL, false));
643     g_assert_cmpint(data.n, ==, 0);
644     g_assert_cmpint(data.active, ==, 10);
645
646     event_notifier_set(&data.e);
647     g_assert(g_main_context_iteration(NULL, false));
648     g_assert_cmpint(data.n, ==, 1);
649     g_assert_cmpint(data.active, ==, 9);
650     g_assert(g_main_context_iteration(NULL, false));
651
652     while (g_main_context_iteration(NULL, false));
653     g_assert_cmpint(data.n, ==, 10);
654     g_assert_cmpint(data.active, ==, 0);
655     g_assert(!g_main_context_iteration(NULL, false));
656
657     aio_set_event_notifier(ctx, &data.e, NULL);
658     while (g_main_context_iteration(NULL, false));
659     event_notifier_cleanup(&data.e);
660 }
661
662 static void test_source_wait_event_notifier_noflush(void)
663 {
664     EventNotifierTestData data = { .n = 0 };
665     EventNotifierTestData dummy = { .n = 0, .active = 1 };
666
667     event_notifier_init(&data.e, false);
668     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
669
670     while (g_main_context_iteration(NULL, false));
671     g_assert_cmpint(data.n, ==, 0);
672
673     /* Until there is an active descriptor, glib may or may not call
674      * event_ready_cb.  Still, it must not block.  */
675     event_notifier_set(&data.e);
676     g_main_context_iteration(NULL, true);
677     data.n = 0;
678
679     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
680     event_notifier_init(&dummy.e, false);
681     aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
682
683     event_notifier_set(&data.e);
684     g_assert(g_main_context_iteration(NULL, false));
685     g_assert_cmpint(data.n, ==, 1);
686     g_assert(!g_main_context_iteration(NULL, false));
687     g_assert_cmpint(data.n, ==, 1);
688
689     event_notifier_set(&data.e);
690     g_assert(g_main_context_iteration(NULL, false));
691     g_assert_cmpint(data.n, ==, 2);
692     g_assert(!g_main_context_iteration(NULL, false));
693     g_assert_cmpint(data.n, ==, 2);
694
695     event_notifier_set(&dummy.e);
696     while (g_main_context_iteration(NULL, false));
697     g_assert_cmpint(data.n, ==, 2);
698     g_assert_cmpint(dummy.n, ==, 1);
699     g_assert_cmpint(dummy.active, ==, 0);
700
701     aio_set_event_notifier(ctx, &dummy.e, NULL);
702     event_notifier_cleanup(&dummy.e);
703
704     aio_set_event_notifier(ctx, &data.e, NULL);
705     while (g_main_context_iteration(NULL, false));
706     g_assert_cmpint(data.n, ==, 2);
707
708     event_notifier_cleanup(&data.e);
709 }
710
711 static void test_source_timer_schedule(void)
712 {
713     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
714                            .max = 2,
715                            .clock_type = QEMU_CLOCK_VIRTUAL };
716     int pipefd[2];
717     int64_t expiry;
718
719     /* aio_poll will not block to wait for timers to complete unless it has
720      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
721      */
722     g_assert(!qemu_pipe(pipefd));
723     qemu_set_nonblock(pipefd[0]);
724     qemu_set_nonblock(pipefd[1]);
725
726     aio_set_fd_handler(ctx, pipefd[0],
727                        dummy_io_handler_read, NULL, NULL);
728     do {} while (g_main_context_iteration(NULL, false));
729
730     aio_timer_init(ctx, &data.timer, data.clock_type,
731                    SCALE_NS, timer_test_cb, &data);
732     expiry = qemu_clock_get_ns(data.clock_type) +
733         data.ns;
734     timer_mod(&data.timer, expiry);
735
736     g_assert_cmpint(data.n, ==, 0);
737
738     g_usleep(1 * G_USEC_PER_SEC);
739     g_assert_cmpint(data.n, ==, 0);
740
741     g_assert(g_main_context_iteration(NULL, false));
742     g_assert_cmpint(data.n, ==, 1);
743
744     /* The comment above was not kidding when it said this wakes up itself */
745     do {
746         g_assert(g_main_context_iteration(NULL, true));
747     } while (qemu_clock_get_ns(data.clock_type) <= expiry);
748     g_usleep(1 * G_USEC_PER_SEC);
749     g_main_context_iteration(NULL, false);
750
751     g_assert_cmpint(data.n, ==, 2);
752
753     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
754     close(pipefd[0]);
755     close(pipefd[1]);
756
757     timer_del(&data.timer);
758 }
759
760
761 /* End of tests.  */
762
763 int main(int argc, char **argv)
764 {
765     GSource *src;
766
767     init_clocks();
768
769     ctx = aio_context_new();
770     src = aio_get_g_source(ctx);
771     g_source_attach(src, NULL);
772     g_source_unref(src);
773
774     while (g_main_context_iteration(NULL, false));
775
776     g_test_init(&argc, &argv, NULL);
777     g_test_add_func("/aio/notify",                  test_notify);
778     g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
779     g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
780     g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
781     g_test_add_func("/aio/bh/delete",               test_bh_delete);
782     g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
783     g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
784     g_test_add_func("/aio/bh/flush",                test_bh_flush);
785     g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
786     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
787     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
788     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
789     g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
790
791     g_test_add_func("/aio-gsource/notify",                  test_source_notify);
792     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
793     g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
794     g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
795     g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
796     g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
797     g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
798     g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
799     g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
800     g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
801     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
802     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
803     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
804     g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
805     return g_test_run();
806 }
This page took 0.066981 seconds and 4 git commands to generate.