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