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