root / tests / test-aio.c @ f2e5dca4
History | View | Annotate | Download (19.5 kB)
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 |
|
16 |
AioContext *ctx; |
17 |
|
18 |
typedef struct { |
19 |
EventNotifier e; |
20 |
int n;
|
21 |
int active;
|
22 |
bool auto_set;
|
23 |
} EventNotifierTestData; |
24 |
|
25 |
/* Wait until there are no more BHs or AIO requests */
|
26 |
static void wait_for_aio(void) |
27 |
{ |
28 |
while (aio_poll(ctx, true)) { |
29 |
/* Do nothing */
|
30 |
} |
31 |
} |
32 |
|
33 |
/* Wait until event notifier becomes inactive */
|
34 |
static void wait_until_inactive(EventNotifierTestData *data) |
35 |
{ |
36 |
while (data->active > 0) { |
37 |
aio_poll(ctx, true);
|
38 |
} |
39 |
} |
40 |
|
41 |
/* Simple callbacks for testing. */
|
42 |
|
43 |
typedef struct { |
44 |
QEMUBH *bh; |
45 |
int n;
|
46 |
int max;
|
47 |
} BHTestData; |
48 |
|
49 |
static void bh_test_cb(void *opaque) |
50 |
{ |
51 |
BHTestData *data = opaque; |
52 |
if (++data->n < data->max) {
|
53 |
qemu_bh_schedule(data->bh); |
54 |
} |
55 |
} |
56 |
|
57 |
static void bh_delete_cb(void *opaque) |
58 |
{ |
59 |
BHTestData *data = opaque; |
60 |
if (++data->n < data->max) {
|
61 |
qemu_bh_schedule(data->bh); |
62 |
} else {
|
63 |
qemu_bh_delete(data->bh); |
64 |
data->bh = NULL;
|
65 |
} |
66 |
} |
67 |
|
68 |
static void event_ready_cb(EventNotifier *e) |
69 |
{ |
70 |
EventNotifierTestData *data = container_of(e, EventNotifierTestData, e); |
71 |
g_assert(event_notifier_test_and_clear(e)); |
72 |
data->n++; |
73 |
if (data->active > 0) { |
74 |
data->active--; |
75 |
} |
76 |
if (data->auto_set && data->active) {
|
77 |
event_notifier_set(e); |
78 |
} |
79 |
} |
80 |
|
81 |
/* Tests using aio_*. */
|
82 |
|
83 |
static void test_notify(void) |
84 |
{ |
85 |
g_assert(!aio_poll(ctx, false));
|
86 |
aio_notify(ctx); |
87 |
g_assert(!aio_poll(ctx, true));
|
88 |
g_assert(!aio_poll(ctx, false));
|
89 |
} |
90 |
|
91 |
static void test_bh_schedule(void) |
92 |
{ |
93 |
BHTestData data = { .n = 0 };
|
94 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
95 |
|
96 |
qemu_bh_schedule(data.bh); |
97 |
g_assert_cmpint(data.n, ==, 0);
|
98 |
|
99 |
g_assert(aio_poll(ctx, true));
|
100 |
g_assert_cmpint(data.n, ==, 1);
|
101 |
|
102 |
g_assert(!aio_poll(ctx, false));
|
103 |
g_assert_cmpint(data.n, ==, 1);
|
104 |
qemu_bh_delete(data.bh); |
105 |
} |
106 |
|
107 |
static void test_bh_schedule10(void) |
108 |
{ |
109 |
BHTestData data = { .n = 0, .max = 10 }; |
110 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
111 |
|
112 |
qemu_bh_schedule(data.bh); |
113 |
g_assert_cmpint(data.n, ==, 0);
|
114 |
|
115 |
g_assert(aio_poll(ctx, false));
|
116 |
g_assert_cmpint(data.n, ==, 1);
|
117 |
|
118 |
g_assert(aio_poll(ctx, true));
|
119 |
g_assert_cmpint(data.n, ==, 2);
|
120 |
|
121 |
wait_for_aio(); |
122 |
g_assert_cmpint(data.n, ==, 10);
|
123 |
|
124 |
g_assert(!aio_poll(ctx, false));
|
125 |
g_assert_cmpint(data.n, ==, 10);
|
126 |
qemu_bh_delete(data.bh); |
127 |
} |
128 |
|
129 |
static void test_bh_cancel(void) |
130 |
{ |
131 |
BHTestData data = { .n = 0 };
|
132 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
133 |
|
134 |
qemu_bh_schedule(data.bh); |
135 |
g_assert_cmpint(data.n, ==, 0);
|
136 |
|
137 |
qemu_bh_cancel(data.bh); |
138 |
g_assert_cmpint(data.n, ==, 0);
|
139 |
|
140 |
g_assert(!aio_poll(ctx, false));
|
141 |
g_assert_cmpint(data.n, ==, 0);
|
142 |
qemu_bh_delete(data.bh); |
143 |
} |
144 |
|
145 |
static void test_bh_delete(void) |
146 |
{ |
147 |
BHTestData data = { .n = 0 };
|
148 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
149 |
|
150 |
qemu_bh_schedule(data.bh); |
151 |
g_assert_cmpint(data.n, ==, 0);
|
152 |
|
153 |
qemu_bh_delete(data.bh); |
154 |
g_assert_cmpint(data.n, ==, 0);
|
155 |
|
156 |
g_assert(!aio_poll(ctx, false));
|
157 |
g_assert_cmpint(data.n, ==, 0);
|
158 |
} |
159 |
|
160 |
static void test_bh_delete_from_cb(void) |
161 |
{ |
162 |
BHTestData data1 = { .n = 0, .max = 1 }; |
163 |
|
164 |
data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); |
165 |
|
166 |
qemu_bh_schedule(data1.bh); |
167 |
g_assert_cmpint(data1.n, ==, 0);
|
168 |
|
169 |
wait_for_aio(); |
170 |
g_assert_cmpint(data1.n, ==, data1.max); |
171 |
g_assert(data1.bh == NULL);
|
172 |
|
173 |
g_assert(!aio_poll(ctx, false));
|
174 |
g_assert(!aio_poll(ctx, true));
|
175 |
} |
176 |
|
177 |
static void test_bh_delete_from_cb_many(void) |
178 |
{ |
179 |
BHTestData data1 = { .n = 0, .max = 1 }; |
180 |
BHTestData data2 = { .n = 0, .max = 3 }; |
181 |
BHTestData data3 = { .n = 0, .max = 2 }; |
182 |
BHTestData data4 = { .n = 0, .max = 4 }; |
183 |
|
184 |
data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); |
185 |
data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); |
186 |
data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); |
187 |
data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); |
188 |
|
189 |
qemu_bh_schedule(data1.bh); |
190 |
qemu_bh_schedule(data2.bh); |
191 |
qemu_bh_schedule(data3.bh); |
192 |
qemu_bh_schedule(data4.bh); |
193 |
g_assert_cmpint(data1.n, ==, 0);
|
194 |
g_assert_cmpint(data2.n, ==, 0);
|
195 |
g_assert_cmpint(data3.n, ==, 0);
|
196 |
g_assert_cmpint(data4.n, ==, 0);
|
197 |
|
198 |
g_assert(aio_poll(ctx, false));
|
199 |
g_assert_cmpint(data1.n, ==, 1);
|
200 |
g_assert_cmpint(data2.n, ==, 1);
|
201 |
g_assert_cmpint(data3.n, ==, 1);
|
202 |
g_assert_cmpint(data4.n, ==, 1);
|
203 |
g_assert(data1.bh == NULL);
|
204 |
|
205 |
wait_for_aio(); |
206 |
g_assert_cmpint(data1.n, ==, data1.max); |
207 |
g_assert_cmpint(data2.n, ==, data2.max); |
208 |
g_assert_cmpint(data3.n, ==, data3.max); |
209 |
g_assert_cmpint(data4.n, ==, data4.max); |
210 |
g_assert(data1.bh == NULL);
|
211 |
g_assert(data2.bh == NULL);
|
212 |
g_assert(data3.bh == NULL);
|
213 |
g_assert(data4.bh == NULL);
|
214 |
} |
215 |
|
216 |
static void test_bh_flush(void) |
217 |
{ |
218 |
BHTestData data = { .n = 0 };
|
219 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
220 |
|
221 |
qemu_bh_schedule(data.bh); |
222 |
g_assert_cmpint(data.n, ==, 0);
|
223 |
|
224 |
wait_for_aio(); |
225 |
g_assert_cmpint(data.n, ==, 1);
|
226 |
|
227 |
g_assert(!aio_poll(ctx, false));
|
228 |
g_assert_cmpint(data.n, ==, 1);
|
229 |
qemu_bh_delete(data.bh); |
230 |
} |
231 |
|
232 |
static void test_set_event_notifier(void) |
233 |
{ |
234 |
EventNotifierTestData data = { .n = 0, .active = 0 }; |
235 |
event_notifier_init(&data.e, false);
|
236 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
237 |
g_assert(!aio_poll(ctx, false));
|
238 |
g_assert_cmpint(data.n, ==, 0);
|
239 |
|
240 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
241 |
g_assert(!aio_poll(ctx, false));
|
242 |
g_assert_cmpint(data.n, ==, 0);
|
243 |
event_notifier_cleanup(&data.e); |
244 |
} |
245 |
|
246 |
static void test_wait_event_notifier(void) |
247 |
{ |
248 |
EventNotifierTestData data = { .n = 0, .active = 1 }; |
249 |
event_notifier_init(&data.e, false);
|
250 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
251 |
g_assert(!aio_poll(ctx, false));
|
252 |
g_assert_cmpint(data.n, ==, 0);
|
253 |
g_assert_cmpint(data.active, ==, 1);
|
254 |
|
255 |
event_notifier_set(&data.e); |
256 |
g_assert(aio_poll(ctx, false));
|
257 |
g_assert_cmpint(data.n, ==, 1);
|
258 |
g_assert_cmpint(data.active, ==, 0);
|
259 |
|
260 |
g_assert(!aio_poll(ctx, false));
|
261 |
g_assert_cmpint(data.n, ==, 1);
|
262 |
g_assert_cmpint(data.active, ==, 0);
|
263 |
|
264 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
265 |
g_assert(!aio_poll(ctx, false));
|
266 |
g_assert_cmpint(data.n, ==, 1);
|
267 |
|
268 |
event_notifier_cleanup(&data.e); |
269 |
} |
270 |
|
271 |
static void test_flush_event_notifier(void) |
272 |
{ |
273 |
EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; |
274 |
event_notifier_init(&data.e, false);
|
275 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
276 |
g_assert(!aio_poll(ctx, false));
|
277 |
g_assert_cmpint(data.n, ==, 0);
|
278 |
g_assert_cmpint(data.active, ==, 10);
|
279 |
|
280 |
event_notifier_set(&data.e); |
281 |
g_assert(aio_poll(ctx, false));
|
282 |
g_assert_cmpint(data.n, ==, 1);
|
283 |
g_assert_cmpint(data.active, ==, 9);
|
284 |
g_assert(aio_poll(ctx, false));
|
285 |
|
286 |
wait_until_inactive(&data); |
287 |
g_assert_cmpint(data.n, ==, 10);
|
288 |
g_assert_cmpint(data.active, ==, 0);
|
289 |
g_assert(!aio_poll(ctx, false));
|
290 |
|
291 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
292 |
g_assert(!aio_poll(ctx, false));
|
293 |
event_notifier_cleanup(&data.e); |
294 |
} |
295 |
|
296 |
static void test_wait_event_notifier_noflush(void) |
297 |
{ |
298 |
EventNotifierTestData data = { .n = 0 };
|
299 |
EventNotifierTestData dummy = { .n = 0, .active = 1 }; |
300 |
|
301 |
event_notifier_init(&data.e, false);
|
302 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
303 |
|
304 |
g_assert(!aio_poll(ctx, false));
|
305 |
g_assert_cmpint(data.n, ==, 0);
|
306 |
|
307 |
/* Until there is an active descriptor, aio_poll may or may not call
|
308 |
* event_ready_cb. Still, it must not block. */
|
309 |
event_notifier_set(&data.e); |
310 |
g_assert(aio_poll(ctx, true));
|
311 |
data.n = 0;
|
312 |
|
313 |
/* An active event notifier forces aio_poll to look at EventNotifiers. */
|
314 |
event_notifier_init(&dummy.e, false);
|
315 |
aio_set_event_notifier(ctx, &dummy.e, event_ready_cb); |
316 |
|
317 |
event_notifier_set(&data.e); |
318 |
g_assert(aio_poll(ctx, false));
|
319 |
g_assert_cmpint(data.n, ==, 1);
|
320 |
g_assert(!aio_poll(ctx, false));
|
321 |
g_assert_cmpint(data.n, ==, 1);
|
322 |
|
323 |
event_notifier_set(&data.e); |
324 |
g_assert(aio_poll(ctx, false));
|
325 |
g_assert_cmpint(data.n, ==, 2);
|
326 |
g_assert(!aio_poll(ctx, false));
|
327 |
g_assert_cmpint(data.n, ==, 2);
|
328 |
|
329 |
event_notifier_set(&dummy.e); |
330 |
wait_until_inactive(&dummy); |
331 |
g_assert_cmpint(data.n, ==, 2);
|
332 |
g_assert_cmpint(dummy.n, ==, 1);
|
333 |
g_assert_cmpint(dummy.active, ==, 0);
|
334 |
|
335 |
aio_set_event_notifier(ctx, &dummy.e, NULL);
|
336 |
event_notifier_cleanup(&dummy.e); |
337 |
|
338 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
339 |
g_assert(!aio_poll(ctx, false));
|
340 |
g_assert_cmpint(data.n, ==, 2);
|
341 |
|
342 |
event_notifier_cleanup(&data.e); |
343 |
} |
344 |
|
345 |
/* Now the same tests, using the context as a GSource. They are
|
346 |
* very similar to the ones above, with g_main_context_iteration
|
347 |
* replacing aio_poll. However:
|
348 |
* - sometimes both the AioContext and the glib main loop wake
|
349 |
* themselves up. Hence, some "g_assert(!aio_poll(ctx, false));"
|
350 |
* are replaced by "while (g_main_context_iteration(NULL, false));".
|
351 |
* - there is no exact replacement for a blocking wait.
|
352 |
* "while (g_main_context_iteration(NULL, true)" seems to work,
|
353 |
* but it is not documented _why_ it works. For these tests a
|
354 |
* non-blocking loop like "while (g_main_context_iteration(NULL, false)"
|
355 |
* works well, and that's what I am using.
|
356 |
*/
|
357 |
|
358 |
static void test_source_notify(void) |
359 |
{ |
360 |
while (g_main_context_iteration(NULL, false)); |
361 |
aio_notify(ctx); |
362 |
g_assert(g_main_context_iteration(NULL, true)); |
363 |
g_assert(!g_main_context_iteration(NULL, false)); |
364 |
} |
365 |
|
366 |
static void test_source_flush(void) |
367 |
{ |
368 |
g_assert(!g_main_context_iteration(NULL, false)); |
369 |
aio_notify(ctx); |
370 |
while (g_main_context_iteration(NULL, false)); |
371 |
g_assert(!g_main_context_iteration(NULL, false)); |
372 |
} |
373 |
|
374 |
static void test_source_bh_schedule(void) |
375 |
{ |
376 |
BHTestData data = { .n = 0 };
|
377 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
378 |
|
379 |
qemu_bh_schedule(data.bh); |
380 |
g_assert_cmpint(data.n, ==, 0);
|
381 |
|
382 |
g_assert(g_main_context_iteration(NULL, true)); |
383 |
g_assert_cmpint(data.n, ==, 1);
|
384 |
|
385 |
g_assert(!g_main_context_iteration(NULL, false)); |
386 |
g_assert_cmpint(data.n, ==, 1);
|
387 |
qemu_bh_delete(data.bh); |
388 |
} |
389 |
|
390 |
static void test_source_bh_schedule10(void) |
391 |
{ |
392 |
BHTestData data = { .n = 0, .max = 10 }; |
393 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
394 |
|
395 |
qemu_bh_schedule(data.bh); |
396 |
g_assert_cmpint(data.n, ==, 0);
|
397 |
|
398 |
g_assert(g_main_context_iteration(NULL, false)); |
399 |
g_assert_cmpint(data.n, ==, 1);
|
400 |
|
401 |
g_assert(g_main_context_iteration(NULL, true)); |
402 |
g_assert_cmpint(data.n, ==, 2);
|
403 |
|
404 |
while (g_main_context_iteration(NULL, false)); |
405 |
g_assert_cmpint(data.n, ==, 10);
|
406 |
|
407 |
g_assert(!g_main_context_iteration(NULL, false)); |
408 |
g_assert_cmpint(data.n, ==, 10);
|
409 |
qemu_bh_delete(data.bh); |
410 |
} |
411 |
|
412 |
static void test_source_bh_cancel(void) |
413 |
{ |
414 |
BHTestData data = { .n = 0 };
|
415 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
416 |
|
417 |
qemu_bh_schedule(data.bh); |
418 |
g_assert_cmpint(data.n, ==, 0);
|
419 |
|
420 |
qemu_bh_cancel(data.bh); |
421 |
g_assert_cmpint(data.n, ==, 0);
|
422 |
|
423 |
while (g_main_context_iteration(NULL, false)); |
424 |
g_assert_cmpint(data.n, ==, 0);
|
425 |
qemu_bh_delete(data.bh); |
426 |
} |
427 |
|
428 |
static void test_source_bh_delete(void) |
429 |
{ |
430 |
BHTestData data = { .n = 0 };
|
431 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
432 |
|
433 |
qemu_bh_schedule(data.bh); |
434 |
g_assert_cmpint(data.n, ==, 0);
|
435 |
|
436 |
qemu_bh_delete(data.bh); |
437 |
g_assert_cmpint(data.n, ==, 0);
|
438 |
|
439 |
while (g_main_context_iteration(NULL, false)); |
440 |
g_assert_cmpint(data.n, ==, 0);
|
441 |
} |
442 |
|
443 |
static void test_source_bh_delete_from_cb(void) |
444 |
{ |
445 |
BHTestData data1 = { .n = 0, .max = 1 }; |
446 |
|
447 |
data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); |
448 |
|
449 |
qemu_bh_schedule(data1.bh); |
450 |
g_assert_cmpint(data1.n, ==, 0);
|
451 |
|
452 |
g_main_context_iteration(NULL, true); |
453 |
g_assert_cmpint(data1.n, ==, data1.max); |
454 |
g_assert(data1.bh == NULL);
|
455 |
|
456 |
g_assert(!g_main_context_iteration(NULL, false)); |
457 |
} |
458 |
|
459 |
static void test_source_bh_delete_from_cb_many(void) |
460 |
{ |
461 |
BHTestData data1 = { .n = 0, .max = 1 }; |
462 |
BHTestData data2 = { .n = 0, .max = 3 }; |
463 |
BHTestData data3 = { .n = 0, .max = 2 }; |
464 |
BHTestData data4 = { .n = 0, .max = 4 }; |
465 |
|
466 |
data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); |
467 |
data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); |
468 |
data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); |
469 |
data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); |
470 |
|
471 |
qemu_bh_schedule(data1.bh); |
472 |
qemu_bh_schedule(data2.bh); |
473 |
qemu_bh_schedule(data3.bh); |
474 |
qemu_bh_schedule(data4.bh); |
475 |
g_assert_cmpint(data1.n, ==, 0);
|
476 |
g_assert_cmpint(data2.n, ==, 0);
|
477 |
g_assert_cmpint(data3.n, ==, 0);
|
478 |
g_assert_cmpint(data4.n, ==, 0);
|
479 |
|
480 |
g_assert(g_main_context_iteration(NULL, false)); |
481 |
g_assert_cmpint(data1.n, ==, 1);
|
482 |
g_assert_cmpint(data2.n, ==, 1);
|
483 |
g_assert_cmpint(data3.n, ==, 1);
|
484 |
g_assert_cmpint(data4.n, ==, 1);
|
485 |
g_assert(data1.bh == NULL);
|
486 |
|
487 |
while (g_main_context_iteration(NULL, false)); |
488 |
g_assert_cmpint(data1.n, ==, data1.max); |
489 |
g_assert_cmpint(data2.n, ==, data2.max); |
490 |
g_assert_cmpint(data3.n, ==, data3.max); |
491 |
g_assert_cmpint(data4.n, ==, data4.max); |
492 |
g_assert(data1.bh == NULL);
|
493 |
g_assert(data2.bh == NULL);
|
494 |
g_assert(data3.bh == NULL);
|
495 |
g_assert(data4.bh == NULL);
|
496 |
} |
497 |
|
498 |
static void test_source_bh_flush(void) |
499 |
{ |
500 |
BHTestData data = { .n = 0 };
|
501 |
data.bh = aio_bh_new(ctx, bh_test_cb, &data); |
502 |
|
503 |
qemu_bh_schedule(data.bh); |
504 |
g_assert_cmpint(data.n, ==, 0);
|
505 |
|
506 |
g_assert(g_main_context_iteration(NULL, true)); |
507 |
g_assert_cmpint(data.n, ==, 1);
|
508 |
|
509 |
g_assert(!g_main_context_iteration(NULL, false)); |
510 |
g_assert_cmpint(data.n, ==, 1);
|
511 |
qemu_bh_delete(data.bh); |
512 |
} |
513 |
|
514 |
static void test_source_set_event_notifier(void) |
515 |
{ |
516 |
EventNotifierTestData data = { .n = 0, .active = 0 }; |
517 |
event_notifier_init(&data.e, false);
|
518 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
519 |
while (g_main_context_iteration(NULL, false)); |
520 |
g_assert_cmpint(data.n, ==, 0);
|
521 |
|
522 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
523 |
while (g_main_context_iteration(NULL, false)); |
524 |
g_assert_cmpint(data.n, ==, 0);
|
525 |
event_notifier_cleanup(&data.e); |
526 |
} |
527 |
|
528 |
static void test_source_wait_event_notifier(void) |
529 |
{ |
530 |
EventNotifierTestData data = { .n = 0, .active = 1 }; |
531 |
event_notifier_init(&data.e, false);
|
532 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
533 |
g_assert(g_main_context_iteration(NULL, false)); |
534 |
g_assert_cmpint(data.n, ==, 0);
|
535 |
g_assert_cmpint(data.active, ==, 1);
|
536 |
|
537 |
event_notifier_set(&data.e); |
538 |
g_assert(g_main_context_iteration(NULL, false)); |
539 |
g_assert_cmpint(data.n, ==, 1);
|
540 |
g_assert_cmpint(data.active, ==, 0);
|
541 |
|
542 |
while (g_main_context_iteration(NULL, false)); |
543 |
g_assert_cmpint(data.n, ==, 1);
|
544 |
g_assert_cmpint(data.active, ==, 0);
|
545 |
|
546 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
547 |
while (g_main_context_iteration(NULL, false)); |
548 |
g_assert_cmpint(data.n, ==, 1);
|
549 |
|
550 |
event_notifier_cleanup(&data.e); |
551 |
} |
552 |
|
553 |
static void test_source_flush_event_notifier(void) |
554 |
{ |
555 |
EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; |
556 |
event_notifier_init(&data.e, false);
|
557 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
558 |
g_assert(g_main_context_iteration(NULL, false)); |
559 |
g_assert_cmpint(data.n, ==, 0);
|
560 |
g_assert_cmpint(data.active, ==, 10);
|
561 |
|
562 |
event_notifier_set(&data.e); |
563 |
g_assert(g_main_context_iteration(NULL, false)); |
564 |
g_assert_cmpint(data.n, ==, 1);
|
565 |
g_assert_cmpint(data.active, ==, 9);
|
566 |
g_assert(g_main_context_iteration(NULL, false)); |
567 |
|
568 |
while (g_main_context_iteration(NULL, false)); |
569 |
g_assert_cmpint(data.n, ==, 10);
|
570 |
g_assert_cmpint(data.active, ==, 0);
|
571 |
g_assert(!g_main_context_iteration(NULL, false)); |
572 |
|
573 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
574 |
while (g_main_context_iteration(NULL, false)); |
575 |
event_notifier_cleanup(&data.e); |
576 |
} |
577 |
|
578 |
static void test_source_wait_event_notifier_noflush(void) |
579 |
{ |
580 |
EventNotifierTestData data = { .n = 0 };
|
581 |
EventNotifierTestData dummy = { .n = 0, .active = 1 }; |
582 |
|
583 |
event_notifier_init(&data.e, false);
|
584 |
aio_set_event_notifier(ctx, &data.e, event_ready_cb); |
585 |
|
586 |
while (g_main_context_iteration(NULL, false)); |
587 |
g_assert_cmpint(data.n, ==, 0);
|
588 |
|
589 |
/* Until there is an active descriptor, glib may or may not call
|
590 |
* event_ready_cb. Still, it must not block. */
|
591 |
event_notifier_set(&data.e); |
592 |
g_main_context_iteration(NULL, true); |
593 |
data.n = 0;
|
594 |
|
595 |
/* An active event notifier forces aio_poll to look at EventNotifiers. */
|
596 |
event_notifier_init(&dummy.e, false);
|
597 |
aio_set_event_notifier(ctx, &dummy.e, event_ready_cb); |
598 |
|
599 |
event_notifier_set(&data.e); |
600 |
g_assert(g_main_context_iteration(NULL, false)); |
601 |
g_assert_cmpint(data.n, ==, 1);
|
602 |
g_assert(!g_main_context_iteration(NULL, false)); |
603 |
g_assert_cmpint(data.n, ==, 1);
|
604 |
|
605 |
event_notifier_set(&data.e); |
606 |
g_assert(g_main_context_iteration(NULL, false)); |
607 |
g_assert_cmpint(data.n, ==, 2);
|
608 |
g_assert(!g_main_context_iteration(NULL, false)); |
609 |
g_assert_cmpint(data.n, ==, 2);
|
610 |
|
611 |
event_notifier_set(&dummy.e); |
612 |
while (g_main_context_iteration(NULL, false)); |
613 |
g_assert_cmpint(data.n, ==, 2);
|
614 |
g_assert_cmpint(dummy.n, ==, 1);
|
615 |
g_assert_cmpint(dummy.active, ==, 0);
|
616 |
|
617 |
aio_set_event_notifier(ctx, &dummy.e, NULL);
|
618 |
event_notifier_cleanup(&dummy.e); |
619 |
|
620 |
aio_set_event_notifier(ctx, &data.e, NULL);
|
621 |
while (g_main_context_iteration(NULL, false)); |
622 |
g_assert_cmpint(data.n, ==, 2);
|
623 |
|
624 |
event_notifier_cleanup(&data.e); |
625 |
} |
626 |
|
627 |
/* End of tests. */
|
628 |
|
629 |
int main(int argc, char **argv) |
630 |
{ |
631 |
GSource *src; |
632 |
|
633 |
ctx = aio_context_new(); |
634 |
src = aio_get_g_source(ctx); |
635 |
g_source_attach(src, NULL);
|
636 |
g_source_unref(src); |
637 |
|
638 |
while (g_main_context_iteration(NULL, false)); |
639 |
|
640 |
g_test_init(&argc, &argv, NULL);
|
641 |
g_test_add_func("/aio/notify", test_notify);
|
642 |
g_test_add_func("/aio/bh/schedule", test_bh_schedule);
|
643 |
g_test_add_func("/aio/bh/schedule10", test_bh_schedule10);
|
644 |
g_test_add_func("/aio/bh/cancel", test_bh_cancel);
|
645 |
g_test_add_func("/aio/bh/delete", test_bh_delete);
|
646 |
g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb);
|
647 |
g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
|
648 |
g_test_add_func("/aio/bh/flush", test_bh_flush);
|
649 |
g_test_add_func("/aio/event/add-remove", test_set_event_notifier);
|
650 |
g_test_add_func("/aio/event/wait", test_wait_event_notifier);
|
651 |
g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush);
|
652 |
g_test_add_func("/aio/event/flush", test_flush_event_notifier);
|
653 |
|
654 |
g_test_add_func("/aio-gsource/notify", test_source_notify);
|
655 |
g_test_add_func("/aio-gsource/flush", test_source_flush);
|
656 |
g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule);
|
657 |
g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10);
|
658 |
g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel);
|
659 |
g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete);
|
660 |
g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb);
|
661 |
g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
|
662 |
g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush);
|
663 |
g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier);
|
664 |
g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier);
|
665 |
g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush);
|
666 |
g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier);
|
667 |
return g_test_run();
|
668 |
} |