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