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