Statistics
| Branch: | Revision:

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
}