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