]> Git Repo - qemu.git/blob - tests/test-aio.c
Merge remote-tracking branch 'remotes/berrange/tags/pull-qcrypto-next-2016-02-02...
[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         set_event_notifier(ctx, &data.e, NULL);
397         event_notifier_cleanup(&data.e);
398     }
399 }
400
401 static void test_wait_event_notifier_noflush(void)
402 {
403     EventNotifierTestData data = { .n = 0 };
404     EventNotifierTestData dummy = { .n = 0, .active = 1 };
405
406     event_notifier_init(&data.e, false);
407     set_event_notifier(ctx, &data.e, event_ready_cb);
408
409     g_assert(!aio_poll(ctx, false));
410     g_assert_cmpint(data.n, ==, 0);
411
412     /* Until there is an active descriptor, aio_poll may or may not call
413      * event_ready_cb.  Still, it must not block.  */
414     event_notifier_set(&data.e);
415     g_assert(aio_poll(ctx, true));
416     data.n = 0;
417
418     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
419     event_notifier_init(&dummy.e, false);
420     set_event_notifier(ctx, &dummy.e, event_ready_cb);
421
422     event_notifier_set(&data.e);
423     g_assert(aio_poll(ctx, false));
424     g_assert_cmpint(data.n, ==, 1);
425     g_assert(!aio_poll(ctx, false));
426     g_assert_cmpint(data.n, ==, 1);
427
428     event_notifier_set(&data.e);
429     g_assert(aio_poll(ctx, false));
430     g_assert_cmpint(data.n, ==, 2);
431     g_assert(!aio_poll(ctx, false));
432     g_assert_cmpint(data.n, ==, 2);
433
434     event_notifier_set(&dummy.e);
435     wait_until_inactive(&dummy);
436     g_assert_cmpint(data.n, ==, 2);
437     g_assert_cmpint(dummy.n, ==, 1);
438     g_assert_cmpint(dummy.active, ==, 0);
439
440     set_event_notifier(ctx, &dummy.e, NULL);
441     event_notifier_cleanup(&dummy.e);
442
443     set_event_notifier(ctx, &data.e, NULL);
444     g_assert(!aio_poll(ctx, false));
445     g_assert_cmpint(data.n, ==, 2);
446
447     event_notifier_cleanup(&data.e);
448 }
449
450 static void test_timer_schedule(void)
451 {
452     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
453                            .max = 2,
454                            .clock_type = QEMU_CLOCK_VIRTUAL };
455     EventNotifier e;
456
457     /* aio_poll will not block to wait for timers to complete unless it has
458      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
459      */
460     event_notifier_init(&e, false);
461     set_event_notifier(ctx, &e, dummy_io_handler_read);
462     aio_poll(ctx, false);
463
464     aio_timer_init(ctx, &data.timer, data.clock_type,
465                    SCALE_NS, timer_test_cb, &data);
466     timer_mod(&data.timer,
467               qemu_clock_get_ns(data.clock_type) +
468               data.ns);
469
470     g_assert_cmpint(data.n, ==, 0);
471
472     /* timer_mod may well cause an event notifer to have gone off,
473      * so clear that
474      */
475     do {} while (aio_poll(ctx, false));
476
477     g_assert(!aio_poll(ctx, false));
478     g_assert_cmpint(data.n, ==, 0);
479
480     g_usleep(1 * G_USEC_PER_SEC);
481     g_assert_cmpint(data.n, ==, 0);
482
483     g_assert(aio_poll(ctx, false));
484     g_assert_cmpint(data.n, ==, 1);
485
486     /* timer_mod called by our callback */
487     do {} while (aio_poll(ctx, false));
488
489     g_assert(!aio_poll(ctx, false));
490     g_assert_cmpint(data.n, ==, 1);
491
492     g_assert(aio_poll(ctx, true));
493     g_assert_cmpint(data.n, ==, 2);
494
495     /* As max is now 2, an event notifier should not have gone off */
496
497     g_assert(!aio_poll(ctx, false));
498     g_assert_cmpint(data.n, ==, 2);
499
500     set_event_notifier(ctx, &e, NULL);
501     event_notifier_cleanup(&e);
502
503     timer_del(&data.timer);
504 }
505
506 /* Now the same tests, using the context as a GSource.  They are
507  * very similar to the ones above, with g_main_context_iteration
508  * replacing aio_poll.  However:
509  * - sometimes both the AioContext and the glib main loop wake
510  *   themselves up.  Hence, some "g_assert(!aio_poll(ctx, false));"
511  *   are replaced by "while (g_main_context_iteration(NULL, false));".
512  * - there is no exact replacement for a blocking wait.
513  *   "while (g_main_context_iteration(NULL, true)" seems to work,
514  *   but it is not documented _why_ it works.  For these tests a
515  *   non-blocking loop like "while (g_main_context_iteration(NULL, false)"
516  *   works well, and that's what I am using.
517  */
518
519 static void test_source_flush(void)
520 {
521     g_assert(!g_main_context_iteration(NULL, false));
522     aio_notify(ctx);
523     while (g_main_context_iteration(NULL, false));
524     g_assert(!g_main_context_iteration(NULL, false));
525 }
526
527 static void test_source_bh_schedule(void)
528 {
529     BHTestData data = { .n = 0 };
530     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
531
532     qemu_bh_schedule(data.bh);
533     g_assert_cmpint(data.n, ==, 0);
534
535     g_assert(g_main_context_iteration(NULL, true));
536     g_assert_cmpint(data.n, ==, 1);
537
538     g_assert(!g_main_context_iteration(NULL, false));
539     g_assert_cmpint(data.n, ==, 1);
540     qemu_bh_delete(data.bh);
541 }
542
543 static void test_source_bh_schedule10(void)
544 {
545     BHTestData data = { .n = 0, .max = 10 };
546     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
547
548     qemu_bh_schedule(data.bh);
549     g_assert_cmpint(data.n, ==, 0);
550
551     g_assert(g_main_context_iteration(NULL, false));
552     g_assert_cmpint(data.n, ==, 1);
553
554     g_assert(g_main_context_iteration(NULL, true));
555     g_assert_cmpint(data.n, ==, 2);
556
557     while (g_main_context_iteration(NULL, false));
558     g_assert_cmpint(data.n, ==, 10);
559
560     g_assert(!g_main_context_iteration(NULL, false));
561     g_assert_cmpint(data.n, ==, 10);
562     qemu_bh_delete(data.bh);
563 }
564
565 static void test_source_bh_cancel(void)
566 {
567     BHTestData data = { .n = 0 };
568     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
569
570     qemu_bh_schedule(data.bh);
571     g_assert_cmpint(data.n, ==, 0);
572
573     qemu_bh_cancel(data.bh);
574     g_assert_cmpint(data.n, ==, 0);
575
576     while (g_main_context_iteration(NULL, false));
577     g_assert_cmpint(data.n, ==, 0);
578     qemu_bh_delete(data.bh);
579 }
580
581 static void test_source_bh_delete(void)
582 {
583     BHTestData data = { .n = 0 };
584     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
585
586     qemu_bh_schedule(data.bh);
587     g_assert_cmpint(data.n, ==, 0);
588
589     qemu_bh_delete(data.bh);
590     g_assert_cmpint(data.n, ==, 0);
591
592     while (g_main_context_iteration(NULL, false));
593     g_assert_cmpint(data.n, ==, 0);
594 }
595
596 static void test_source_bh_delete_from_cb(void)
597 {
598     BHTestData data1 = { .n = 0, .max = 1 };
599
600     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
601
602     qemu_bh_schedule(data1.bh);
603     g_assert_cmpint(data1.n, ==, 0);
604
605     g_main_context_iteration(NULL, true);
606     g_assert_cmpint(data1.n, ==, data1.max);
607     g_assert(data1.bh == NULL);
608
609     g_assert(!g_main_context_iteration(NULL, false));
610 }
611
612 static void test_source_bh_delete_from_cb_many(void)
613 {
614     BHTestData data1 = { .n = 0, .max = 1 };
615     BHTestData data2 = { .n = 0, .max = 3 };
616     BHTestData data3 = { .n = 0, .max = 2 };
617     BHTestData data4 = { .n = 0, .max = 4 };
618
619     data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
620     data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
621     data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
622     data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
623
624     qemu_bh_schedule(data1.bh);
625     qemu_bh_schedule(data2.bh);
626     qemu_bh_schedule(data3.bh);
627     qemu_bh_schedule(data4.bh);
628     g_assert_cmpint(data1.n, ==, 0);
629     g_assert_cmpint(data2.n, ==, 0);
630     g_assert_cmpint(data3.n, ==, 0);
631     g_assert_cmpint(data4.n, ==, 0);
632
633     g_assert(g_main_context_iteration(NULL, false));
634     g_assert_cmpint(data1.n, ==, 1);
635     g_assert_cmpint(data2.n, ==, 1);
636     g_assert_cmpint(data3.n, ==, 1);
637     g_assert_cmpint(data4.n, ==, 1);
638     g_assert(data1.bh == NULL);
639
640     while (g_main_context_iteration(NULL, false));
641     g_assert_cmpint(data1.n, ==, data1.max);
642     g_assert_cmpint(data2.n, ==, data2.max);
643     g_assert_cmpint(data3.n, ==, data3.max);
644     g_assert_cmpint(data4.n, ==, data4.max);
645     g_assert(data1.bh == NULL);
646     g_assert(data2.bh == NULL);
647     g_assert(data3.bh == NULL);
648     g_assert(data4.bh == NULL);
649 }
650
651 static void test_source_bh_flush(void)
652 {
653     BHTestData data = { .n = 0 };
654     data.bh = aio_bh_new(ctx, bh_test_cb, &data);
655
656     qemu_bh_schedule(data.bh);
657     g_assert_cmpint(data.n, ==, 0);
658
659     g_assert(g_main_context_iteration(NULL, true));
660     g_assert_cmpint(data.n, ==, 1);
661
662     g_assert(!g_main_context_iteration(NULL, false));
663     g_assert_cmpint(data.n, ==, 1);
664     qemu_bh_delete(data.bh);
665 }
666
667 static void test_source_set_event_notifier(void)
668 {
669     EventNotifierTestData data = { .n = 0, .active = 0 };
670     event_notifier_init(&data.e, false);
671     set_event_notifier(ctx, &data.e, event_ready_cb);
672     while (g_main_context_iteration(NULL, false));
673     g_assert_cmpint(data.n, ==, 0);
674
675     set_event_notifier(ctx, &data.e, NULL);
676     while (g_main_context_iteration(NULL, false));
677     g_assert_cmpint(data.n, ==, 0);
678     event_notifier_cleanup(&data.e);
679 }
680
681 static void test_source_wait_event_notifier(void)
682 {
683     EventNotifierTestData data = { .n = 0, .active = 1 };
684     event_notifier_init(&data.e, false);
685     set_event_notifier(ctx, &data.e, event_ready_cb);
686     while (g_main_context_iteration(NULL, false));
687     g_assert_cmpint(data.n, ==, 0);
688     g_assert_cmpint(data.active, ==, 1);
689
690     event_notifier_set(&data.e);
691     g_assert(g_main_context_iteration(NULL, false));
692     g_assert_cmpint(data.n, ==, 1);
693     g_assert_cmpint(data.active, ==, 0);
694
695     while (g_main_context_iteration(NULL, false));
696     g_assert_cmpint(data.n, ==, 1);
697     g_assert_cmpint(data.active, ==, 0);
698
699     set_event_notifier(ctx, &data.e, NULL);
700     while (g_main_context_iteration(NULL, false));
701     g_assert_cmpint(data.n, ==, 1);
702
703     event_notifier_cleanup(&data.e);
704 }
705
706 static void test_source_flush_event_notifier(void)
707 {
708     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
709     event_notifier_init(&data.e, false);
710     set_event_notifier(ctx, &data.e, event_ready_cb);
711     while (g_main_context_iteration(NULL, false));
712     g_assert_cmpint(data.n, ==, 0);
713     g_assert_cmpint(data.active, ==, 10);
714
715     event_notifier_set(&data.e);
716     g_assert(g_main_context_iteration(NULL, false));
717     g_assert_cmpint(data.n, ==, 1);
718     g_assert_cmpint(data.active, ==, 9);
719     g_assert(g_main_context_iteration(NULL, false));
720
721     while (g_main_context_iteration(NULL, false));
722     g_assert_cmpint(data.n, ==, 10);
723     g_assert_cmpint(data.active, ==, 0);
724     g_assert(!g_main_context_iteration(NULL, false));
725
726     set_event_notifier(ctx, &data.e, NULL);
727     while (g_main_context_iteration(NULL, false));
728     event_notifier_cleanup(&data.e);
729 }
730
731 static void test_source_wait_event_notifier_noflush(void)
732 {
733     EventNotifierTestData data = { .n = 0 };
734     EventNotifierTestData dummy = { .n = 0, .active = 1 };
735
736     event_notifier_init(&data.e, false);
737     set_event_notifier(ctx, &data.e, event_ready_cb);
738
739     while (g_main_context_iteration(NULL, false));
740     g_assert_cmpint(data.n, ==, 0);
741
742     /* Until there is an active descriptor, glib may or may not call
743      * event_ready_cb.  Still, it must not block.  */
744     event_notifier_set(&data.e);
745     g_main_context_iteration(NULL, true);
746     data.n = 0;
747
748     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
749     event_notifier_init(&dummy.e, false);
750     set_event_notifier(ctx, &dummy.e, event_ready_cb);
751
752     event_notifier_set(&data.e);
753     g_assert(g_main_context_iteration(NULL, false));
754     g_assert_cmpint(data.n, ==, 1);
755     g_assert(!g_main_context_iteration(NULL, false));
756     g_assert_cmpint(data.n, ==, 1);
757
758     event_notifier_set(&data.e);
759     g_assert(g_main_context_iteration(NULL, false));
760     g_assert_cmpint(data.n, ==, 2);
761     g_assert(!g_main_context_iteration(NULL, false));
762     g_assert_cmpint(data.n, ==, 2);
763
764     event_notifier_set(&dummy.e);
765     while (g_main_context_iteration(NULL, false));
766     g_assert_cmpint(data.n, ==, 2);
767     g_assert_cmpint(dummy.n, ==, 1);
768     g_assert_cmpint(dummy.active, ==, 0);
769
770     set_event_notifier(ctx, &dummy.e, NULL);
771     event_notifier_cleanup(&dummy.e);
772
773     set_event_notifier(ctx, &data.e, NULL);
774     while (g_main_context_iteration(NULL, false));
775     g_assert_cmpint(data.n, ==, 2);
776
777     event_notifier_cleanup(&data.e);
778 }
779
780 static void test_source_timer_schedule(void)
781 {
782     TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
783                            .max = 2,
784                            .clock_type = QEMU_CLOCK_VIRTUAL };
785     EventNotifier e;
786     int64_t expiry;
787
788     /* aio_poll will not block to wait for timers to complete unless it has
789      * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
790      */
791     event_notifier_init(&e, false);
792     set_event_notifier(ctx, &e, dummy_io_handler_read);
793     do {} while (g_main_context_iteration(NULL, false));
794
795     aio_timer_init(ctx, &data.timer, data.clock_type,
796                    SCALE_NS, timer_test_cb, &data);
797     expiry = qemu_clock_get_ns(data.clock_type) +
798         data.ns;
799     timer_mod(&data.timer, expiry);
800
801     g_assert_cmpint(data.n, ==, 0);
802
803     g_usleep(1 * G_USEC_PER_SEC);
804     g_assert_cmpint(data.n, ==, 0);
805
806     g_assert(g_main_context_iteration(NULL, true));
807     g_assert_cmpint(data.n, ==, 1);
808     expiry += data.ns;
809
810     while (data.n < 2) {
811         g_main_context_iteration(NULL, true);
812     }
813
814     g_assert_cmpint(data.n, ==, 2);
815     g_assert(qemu_clock_get_ns(data.clock_type) > expiry);
816
817     set_event_notifier(ctx, &e, NULL);
818     event_notifier_cleanup(&e);
819
820     timer_del(&data.timer);
821 }
822
823
824 /* End of tests.  */
825
826 int main(int argc, char **argv)
827 {
828     Error *local_error = NULL;
829     GSource *src;
830
831     init_clocks();
832
833     ctx = aio_context_new(&local_error);
834     if (!ctx) {
835         error_reportf_err(local_error, "Failed to create AIO Context: ");
836         exit(1);
837     }
838     src = aio_get_g_source(ctx);
839     g_source_attach(src, NULL);
840     g_source_unref(src);
841
842     while (g_main_context_iteration(NULL, false));
843
844     g_test_init(&argc, &argv, NULL);
845     g_test_add_func("/aio/acquire",                 test_acquire);
846     g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
847     g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
848     g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
849     g_test_add_func("/aio/bh/delete",               test_bh_delete);
850     g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
851     g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
852     g_test_add_func("/aio/bh/flush",                test_bh_flush);
853     g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
854     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
855     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
856     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
857     g_test_add_func("/aio/external-client",         test_aio_external_client);
858     g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
859
860     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
861     g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
862     g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
863     g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
864     g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
865     g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
866     g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
867     g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
868     g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
869     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
870     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
871     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
872     g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
873     return g_test_run();
874 }
This page took 0.06957 seconds and 4 git commands to generate.