]> Git Repo - qemu.git/blob - tests/test-aio.c
Merge remote-tracking branch 'sstabellini/xen-2013-09-09' 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 #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     g_assert(!aio_poll(ctx, true));
199 }
200
201 static void test_bh_delete_from_cb_many(void)
202 {
203     BHTestData data1 = { .n = 0, .max = 1 };
204     BHTestData data2 = { .n = 0, .max = 3 };
205     BHTestData data3 = { .n = 0, .max = 2 };
206     BHTestData data4 = { .n = 0, .max = 4 };
207
208     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
209     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
210     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
211     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
212
213     qemu_bh_schedule(data1.bh);
214     qemu_bh_schedule(data2.bh);
215     qemu_bh_schedule(data3.bh);
216     qemu_bh_schedule(data4.bh);
217     g_assert_cmpint(data1.n, ==, 0);
218     g_assert_cmpint(data2.n, ==, 0);
219     g_assert_cmpint(data3.n, ==, 0);
220     g_assert_cmpint(data4.n, ==, 0);
221
222     g_assert(aio_poll(ctx, false));
223     g_assert_cmpint(data1.n, ==, 1);
224     g_assert_cmpint(data2.n, ==, 1);
225     g_assert_cmpint(data3.n, ==, 1);
226     g_assert_cmpint(data4.n, ==, 1);
227     g_assert(data1.bh == NULL);
228
229     wait_for_aio();
230     g_assert_cmpint(data1.n, ==, data1.max);
231     g_assert_cmpint(data2.n, ==, data2.max);
232     g_assert_cmpint(data3.n, ==, data3.max);
233     g_assert_cmpint(data4.n, ==, data4.max);
234     g_assert(data1.bh == NULL);
235     g_assert(data2.bh == NULL);
236     g_assert(data3.bh == NULL);
237     g_assert(data4.bh == NULL);
238 }
239
240 static void test_bh_flush(void)
241 {
242     BHTestData data = { .n = 0 };
243     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
244
245     qemu_bh_schedule(data.bh);
246     g_assert_cmpint(data.n, ==, 0);
247
248     wait_for_aio();
249     g_assert_cmpint(data.n, ==, 1);
250
251     g_assert(!aio_poll(ctx, false));
252     g_assert_cmpint(data.n, ==, 1);
253     qemu_bh_delete(data.bh);
254 }
255
256 static void test_set_event_notifier(void)
257 {
258     EventNotifierTestData data = { .n = 0, .active = 0 };
259     event_notifier_init(&data.e, false);
260     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
261     g_assert(!aio_poll(ctx, false));
262     g_assert_cmpint(data.n, ==, 0);
263
264     aio_set_event_notifier(ctx, &data.e, NULL);
265     g_assert(!aio_poll(ctx, false));
266     g_assert_cmpint(data.n, ==, 0);
267     event_notifier_cleanup(&data.e);
268 }
269
270 static void test_wait_event_notifier(void)
271 {
272     EventNotifierTestData data = { .n = 0, .active = 1 };
273     event_notifier_init(&data.e, false);
274     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
275     g_assert(!aio_poll(ctx, false));
276     g_assert_cmpint(data.n, ==, 0);
277     g_assert_cmpint(data.active, ==, 1);
278
279     event_notifier_set(&data.e);
280     g_assert(aio_poll(ctx, false));
281     g_assert_cmpint(data.n, ==, 1);
282     g_assert_cmpint(data.active, ==, 0);
283
284     g_assert(!aio_poll(ctx, false));
285     g_assert_cmpint(data.n, ==, 1);
286     g_assert_cmpint(data.active, ==, 0);
287
288     aio_set_event_notifier(ctx, &data.e, NULL);
289     g_assert(!aio_poll(ctx, false));
290     g_assert_cmpint(data.n, ==, 1);
291
292     event_notifier_cleanup(&data.e);
293 }
294
295 static void test_flush_event_notifier(void)
296 {
297     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
298     event_notifier_init(&data.e, false);
299     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
300     g_assert(!aio_poll(ctx, false));
301     g_assert_cmpint(data.n, ==, 0);
302     g_assert_cmpint(data.active, ==, 10);
303
304     event_notifier_set(&data.e);
305     g_assert(aio_poll(ctx, false));
306     g_assert_cmpint(data.n, ==, 1);
307     g_assert_cmpint(data.active, ==, 9);
308     g_assert(aio_poll(ctx, false));
309
310     wait_until_inactive(&data);
311     g_assert_cmpint(data.n, ==, 10);
312     g_assert_cmpint(data.active, ==, 0);
313     g_assert(!aio_poll(ctx, false));
314
315     aio_set_event_notifier(ctx, &data.e, NULL);
316     g_assert(!aio_poll(ctx, false));
317     event_notifier_cleanup(&data.e);
318 }
319
320 static void test_wait_event_notifier_noflush(void)
321 {
322     EventNotifierTestData data = { .n = 0 };
323     EventNotifierTestData dummy = { .n = 0, .active = 1 };
324
325     event_notifier_init(&data.e, false);
326     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
327
328     g_assert(!aio_poll(ctx, false));
329     g_assert_cmpint(data.n, ==, 0);
330
331     /* Until there is an active descriptor, aio_poll may or may not call
332      * event_ready_cb.  Still, it must not block.  */
333     event_notifier_set(&data.e);
334     g_assert(aio_poll(ctx, true));
335     data.n = 0;
336
337     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
338     event_notifier_init(&dummy.e, false);
339     aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
340
341     event_notifier_set(&data.e);
342     g_assert(aio_poll(ctx, false));
343     g_assert_cmpint(data.n, ==, 1);
344     g_assert(!aio_poll(ctx, false));
345     g_assert_cmpint(data.n, ==, 1);
346
347     event_notifier_set(&data.e);
348     g_assert(aio_poll(ctx, false));
349     g_assert_cmpint(data.n, ==, 2);
350     g_assert(!aio_poll(ctx, false));
351     g_assert_cmpint(data.n, ==, 2);
352
353     event_notifier_set(&dummy.e);
354     wait_until_inactive(&dummy);
355     g_assert_cmpint(data.n, ==, 2);
356     g_assert_cmpint(dummy.n, ==, 1);
357     g_assert_cmpint(dummy.active, ==, 0);
358
359     aio_set_event_notifier(ctx, &dummy.e, NULL);
360     event_notifier_cleanup(&dummy.e);
361
362     aio_set_event_notifier(ctx, &data.e, NULL);
363     g_assert(!aio_poll(ctx, false));
364     g_assert_cmpint(data.n, ==, 2);
365
366     event_notifier_cleanup(&data.e);
367 }
368
369 static void test_timer_schedule(void)
370 {
371     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
372                            .max = 2,
373                            .clock_type = QEMU_CLOCK_VIRTUAL };
374     int pipefd[2];
375
376     /* aio_poll will not block to wait for timers to complete unless it has
377      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
378      */
379     g_assert(!qemu_pipe(pipefd));
380     qemu_set_nonblock(pipefd[0]);
381     qemu_set_nonblock(pipefd[1]);
382
383     aio_set_fd_handler(ctx, pipefd[0],
384                        dummy_io_handler_read, NULL, NULL);
385     aio_poll(ctx, false);
386
387     aio_timer_init(ctx, &data.timer, data.clock_type,
388                    SCALE_NS, timer_test_cb, &data);
389     timer_mod(&data.timer,
390               qemu_clock_get_ns(data.clock_type) +
391               data.ns);
392
393     g_assert_cmpint(data.n, ==, 0);
394
395     /* timer_mod may well cause an event notifer to have gone off,
396      * so clear that
397      */
398     do {} while (aio_poll(ctx, false));
399
400     g_assert(!aio_poll(ctx, false));
401     g_assert_cmpint(data.n, ==, 0);
402
403     g_usleep(1 * G_USEC_PER_SEC);
404     g_assert_cmpint(data.n, ==, 0);
405
406     g_assert(aio_poll(ctx, false));
407     g_assert_cmpint(data.n, ==, 1);
408
409     /* timer_mod called by our callback */
410     do {} while (aio_poll(ctx, false));
411
412     g_assert(!aio_poll(ctx, false));
413     g_assert_cmpint(data.n, ==, 1);
414
415     g_assert(aio_poll(ctx, true));
416     g_assert_cmpint(data.n, ==, 2);
417
418     /* As max is now 2, an event notifier should not have gone off */
419
420     g_assert(!aio_poll(ctx, false));
421     g_assert_cmpint(data.n, ==, 2);
422
423     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
424     close(pipefd[0]);
425     close(pipefd[1]);
426
427     timer_del(&data.timer);
428 }
429
430 /* Now the same tests, using the context as a GSource.  They are
431  * very similar to the ones above, with g_main_context_iteration
432  * replacing aio_poll.  However:
433  * - sometimes both the AioContext and the glib main loop wake
434  *   themselves up.  Hence, some "g_assert(!aio_poll(ctx, false));"
435  *   are replaced by "while (g_main_context_iteration(NULL, false));".
436  * - there is no exact replacement for a blocking wait.
437  *   "while (g_main_context_iteration(NULL, true)" seems to work,
438  *   but it is not documented _why_ it works.  For these tests a
439  *   non-blocking loop like "while (g_main_context_iteration(NULL, false)"
440  *   works well, and that's what I am using.
441  */
442
443 static void test_source_notify(void)
444 {
445     while (g_main_context_iteration(NULL, false));
446     aio_notify(ctx);
447     g_assert(g_main_context_iteration(NULL, true));
448     g_assert(!g_main_context_iteration(NULL, false));
449 }
450
451 static void test_source_flush(void)
452 {
453     g_assert(!g_main_context_iteration(NULL, false));
454     aio_notify(ctx);
455     while (g_main_context_iteration(NULL, false));
456     g_assert(!g_main_context_iteration(NULL, false));
457 }
458
459 static void test_source_bh_schedule(void)
460 {
461     BHTestData data = { .n = 0 };
462     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
463
464     qemu_bh_schedule(data.bh);
465     g_assert_cmpint(data.n, ==, 0);
466
467     g_assert(g_main_context_iteration(NULL, true));
468     g_assert_cmpint(data.n, ==, 1);
469
470     g_assert(!g_main_context_iteration(NULL, false));
471     g_assert_cmpint(data.n, ==, 1);
472     qemu_bh_delete(data.bh);
473 }
474
475 static void test_source_bh_schedule10(void)
476 {
477     BHTestData data = { .n = 0, .max = 10 };
478     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
479
480     qemu_bh_schedule(data.bh);
481     g_assert_cmpint(data.n, ==, 0);
482
483     g_assert(g_main_context_iteration(NULL, false));
484     g_assert_cmpint(data.n, ==, 1);
485
486     g_assert(g_main_context_iteration(NULL, true));
487     g_assert_cmpint(data.n, ==, 2);
488
489     while (g_main_context_iteration(NULL, false));
490     g_assert_cmpint(data.n, ==, 10);
491
492     g_assert(!g_main_context_iteration(NULL, false));
493     g_assert_cmpint(data.n, ==, 10);
494     qemu_bh_delete(data.bh);
495 }
496
497 static void test_source_bh_cancel(void)
498 {
499     BHTestData data = { .n = 0 };
500     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
501
502     qemu_bh_schedule(data.bh);
503     g_assert_cmpint(data.n, ==, 0);
504
505     qemu_bh_cancel(data.bh);
506     g_assert_cmpint(data.n, ==, 0);
507
508     while (g_main_context_iteration(NULL, false));
509     g_assert_cmpint(data.n, ==, 0);
510     qemu_bh_delete(data.bh);
511 }
512
513 static void test_source_bh_delete(void)
514 {
515     BHTestData data = { .n = 0 };
516     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
517
518     qemu_bh_schedule(data.bh);
519     g_assert_cmpint(data.n, ==, 0);
520
521     qemu_bh_delete(data.bh);
522     g_assert_cmpint(data.n, ==, 0);
523
524     while (g_main_context_iteration(NULL, false));
525     g_assert_cmpint(data.n, ==, 0);
526 }
527
528 static void test_source_bh_delete_from_cb(void)
529 {
530     BHTestData data1 = { .n = 0, .max = 1 };
531
532     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
533
534     qemu_bh_schedule(data1.bh);
535     g_assert_cmpint(data1.n, ==, 0);
536
537     g_main_context_iteration(NULL, true);
538     g_assert_cmpint(data1.n, ==, data1.max);
539     g_assert(data1.bh == NULL);
540
541     g_assert(!g_main_context_iteration(NULL, false));
542 }
543
544 static void test_source_bh_delete_from_cb_many(void)
545 {
546     BHTestData data1 = { .n = 0, .max = 1 };
547     BHTestData data2 = { .n = 0, .max = 3 };
548     BHTestData data3 = { .n = 0, .max = 2 };
549     BHTestData data4 = { .n = 0, .max = 4 };
550
551     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
552     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
553     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
554     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
555
556     qemu_bh_schedule(data1.bh);
557     qemu_bh_schedule(data2.bh);
558     qemu_bh_schedule(data3.bh);
559     qemu_bh_schedule(data4.bh);
560     g_assert_cmpint(data1.n, ==, 0);
561     g_assert_cmpint(data2.n, ==, 0);
562     g_assert_cmpint(data3.n, ==, 0);
563     g_assert_cmpint(data4.n, ==, 0);
564
565     g_assert(g_main_context_iteration(NULL, false));
566     g_assert_cmpint(data1.n, ==, 1);
567     g_assert_cmpint(data2.n, ==, 1);
568     g_assert_cmpint(data3.n, ==, 1);
569     g_assert_cmpint(data4.n, ==, 1);
570     g_assert(data1.bh == NULL);
571
572     while (g_main_context_iteration(NULL, false));
573     g_assert_cmpint(data1.n, ==, data1.max);
574     g_assert_cmpint(data2.n, ==, data2.max);
575     g_assert_cmpint(data3.n, ==, data3.max);
576     g_assert_cmpint(data4.n, ==, data4.max);
577     g_assert(data1.bh == NULL);
578     g_assert(data2.bh == NULL);
579     g_assert(data3.bh == NULL);
580     g_assert(data4.bh == NULL);
581 }
582
583 static void test_source_bh_flush(void)
584 {
585     BHTestData data = { .n = 0 };
586     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
587
588     qemu_bh_schedule(data.bh);
589     g_assert_cmpint(data.n, ==, 0);
590
591     g_assert(g_main_context_iteration(NULL, true));
592     g_assert_cmpint(data.n, ==, 1);
593
594     g_assert(!g_main_context_iteration(NULL, false));
595     g_assert_cmpint(data.n, ==, 1);
596     qemu_bh_delete(data.bh);
597 }
598
599 static void test_source_set_event_notifier(void)
600 {
601     EventNotifierTestData data = { .n = 0, .active = 0 };
602     event_notifier_init(&data.e, false);
603     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
604     while (g_main_context_iteration(NULL, false));
605     g_assert_cmpint(data.n, ==, 0);
606
607     aio_set_event_notifier(ctx, &data.e, NULL);
608     while (g_main_context_iteration(NULL, false));
609     g_assert_cmpint(data.n, ==, 0);
610     event_notifier_cleanup(&data.e);
611 }
612
613 static void test_source_wait_event_notifier(void)
614 {
615     EventNotifierTestData data = { .n = 0, .active = 1 };
616     event_notifier_init(&data.e, false);
617     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
618     g_assert(g_main_context_iteration(NULL, false));
619     g_assert_cmpint(data.n, ==, 0);
620     g_assert_cmpint(data.active, ==, 1);
621
622     event_notifier_set(&data.e);
623     g_assert(g_main_context_iteration(NULL, false));
624     g_assert_cmpint(data.n, ==, 1);
625     g_assert_cmpint(data.active, ==, 0);
626
627     while (g_main_context_iteration(NULL, false));
628     g_assert_cmpint(data.n, ==, 1);
629     g_assert_cmpint(data.active, ==, 0);
630
631     aio_set_event_notifier(ctx, &data.e, NULL);
632     while (g_main_context_iteration(NULL, false));
633     g_assert_cmpint(data.n, ==, 1);
634
635     event_notifier_cleanup(&data.e);
636 }
637
638 static void test_source_flush_event_notifier(void)
639 {
640     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
641     event_notifier_init(&data.e, false);
642     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
643     g_assert(g_main_context_iteration(NULL, false));
644     g_assert_cmpint(data.n, ==, 0);
645     g_assert_cmpint(data.active, ==, 10);
646
647     event_notifier_set(&data.e);
648     g_assert(g_main_context_iteration(NULL, false));
649     g_assert_cmpint(data.n, ==, 1);
650     g_assert_cmpint(data.active, ==, 9);
651     g_assert(g_main_context_iteration(NULL, false));
652
653     while (g_main_context_iteration(NULL, false));
654     g_assert_cmpint(data.n, ==, 10);
655     g_assert_cmpint(data.active, ==, 0);
656     g_assert(!g_main_context_iteration(NULL, false));
657
658     aio_set_event_notifier(ctx, &data.e, NULL);
659     while (g_main_context_iteration(NULL, false));
660     event_notifier_cleanup(&data.e);
661 }
662
663 static void test_source_wait_event_notifier_noflush(void)
664 {
665     EventNotifierTestData data = { .n = 0 };
666     EventNotifierTestData dummy = { .n = 0, .active = 1 };
667
668     event_notifier_init(&data.e, false);
669     aio_set_event_notifier(ctx, &data.e, event_ready_cb);
670
671     while (g_main_context_iteration(NULL, false));
672     g_assert_cmpint(data.n, ==, 0);
673
674     /* Until there is an active descriptor, glib may or may not call
675      * event_ready_cb.  Still, it must not block.  */
676     event_notifier_set(&data.e);
677     g_main_context_iteration(NULL, true);
678     data.n = 0;
679
680     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
681     event_notifier_init(&dummy.e, false);
682     aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
683
684     event_notifier_set(&data.e);
685     g_assert(g_main_context_iteration(NULL, false));
686     g_assert_cmpint(data.n, ==, 1);
687     g_assert(!g_main_context_iteration(NULL, false));
688     g_assert_cmpint(data.n, ==, 1);
689
690     event_notifier_set(&data.e);
691     g_assert(g_main_context_iteration(NULL, false));
692     g_assert_cmpint(data.n, ==, 2);
693     g_assert(!g_main_context_iteration(NULL, false));
694     g_assert_cmpint(data.n, ==, 2);
695
696     event_notifier_set(&dummy.e);
697     while (g_main_context_iteration(NULL, false));
698     g_assert_cmpint(data.n, ==, 2);
699     g_assert_cmpint(dummy.n, ==, 1);
700     g_assert_cmpint(dummy.active, ==, 0);
701
702     aio_set_event_notifier(ctx, &dummy.e, NULL);
703     event_notifier_cleanup(&dummy.e);
704
705     aio_set_event_notifier(ctx, &data.e, NULL);
706     while (g_main_context_iteration(NULL, false));
707     g_assert_cmpint(data.n, ==, 2);
708
709     event_notifier_cleanup(&data.e);
710 }
711
712 static void test_source_timer_schedule(void)
713 {
714     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
715                            .max = 2,
716                            .clock_type = QEMU_CLOCK_VIRTUAL };
717     int pipefd[2];
718     int64_t expiry;
719
720     /* aio_poll will not block to wait for timers to complete unless it has
721      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
722      */
723     g_assert(!qemu_pipe(pipefd));
724     qemu_set_nonblock(pipefd[0]);
725     qemu_set_nonblock(pipefd[1]);
726
727     aio_set_fd_handler(ctx, pipefd[0],
728                        dummy_io_handler_read, NULL, NULL);
729     do {} while (g_main_context_iteration(NULL, false));
730
731     aio_timer_init(ctx, &data.timer, data.clock_type,
732                    SCALE_NS, timer_test_cb, &data);
733     expiry = qemu_clock_get_ns(data.clock_type) +
734         data.ns;
735     timer_mod(&data.timer, expiry);
736
737     g_assert_cmpint(data.n, ==, 0);
738
739     g_usleep(1 * G_USEC_PER_SEC);
740     g_assert_cmpint(data.n, ==, 0);
741
742     g_assert(g_main_context_iteration(NULL, false));
743     g_assert_cmpint(data.n, ==, 1);
744
745     /* The comment above was not kidding when it said this wakes up itself */
746     do {
747         g_assert(g_main_context_iteration(NULL, true));
748     } while (qemu_clock_get_ns(data.clock_type) <= expiry);
749     g_usleep(1 * G_USEC_PER_SEC);
750     g_main_context_iteration(NULL, false);
751
752     g_assert_cmpint(data.n, ==, 2);
753
754     aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
755     close(pipefd[0]);
756     close(pipefd[1]);
757
758     timer_del(&data.timer);
759 }
760
761
762 /* End of tests.  */
763
764 int main(int argc, char **argv)
765 {
766     GSource *src;
767
768     init_clocks();
769
770     ctx = aio_context_new();
771     src = aio_get_g_source(ctx);
772     g_source_attach(src, NULL);
773     g_source_unref(src);
774
775     while (g_main_context_iteration(NULL, false));
776
777     g_test_init(&argc, &argv, NULL);
778     g_test_add_func("/aio/notify",                  test_notify);
779     g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
780     g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
781     g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
782     g_test_add_func("/aio/bh/delete",               test_bh_delete);
783     g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
784     g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
785     g_test_add_func("/aio/bh/flush",                test_bh_flush);
786     g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
787     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
788     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
789     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
790     g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
791
792     g_test_add_func("/aio-gsource/notify",                  test_source_notify);
793     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
794     g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
795     g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
796     g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
797     g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
798     g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
799     g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
800     g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
801     g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
802     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
803     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
804     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
805     g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
806     return g_test_run();
807 }
This page took 0.066682 seconds and 4 git commands to generate.