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