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