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