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.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, false, handler, 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_aio_external_client(void)
 387{
 388    int i, j;
 389
 390    for (i = 1; i < 3; i++) {
 391        EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
 392        event_notifier_init(&data.e, false);
 393        aio_set_event_notifier(ctx, &data.e, true, event_ready_cb, NULL);
 394        event_notifier_set(&data.e);
 395        for (j = 0; j < i; j++) {
 396            aio_disable_external(ctx);
 397        }
 398        for (j = 0; j < i; j++) {
 399            assert(!aio_poll(ctx, false));
 400            assert(event_notifier_test_and_clear(&data.e));
 401            event_notifier_set(&data.e);
 402            aio_enable_external(ctx);
 403        }
 404        assert(aio_poll(ctx, false));
 405        set_event_notifier(ctx, &data.e, NULL);
 406        event_notifier_cleanup(&data.e);
 407    }
 408}
 409
 410static void test_wait_event_notifier_noflush(void)
 411{
 412    EventNotifierTestData data = { .n = 0 };
 413    EventNotifierTestData dummy = { .n = 0, .active = 1 };
 414
 415    event_notifier_init(&data.e, false);
 416    set_event_notifier(ctx, &data.e, event_ready_cb);
 417
 418    g_assert(!aio_poll(ctx, false));
 419    g_assert_cmpint(data.n, ==, 0);
 420
 421    /* Until there is an active descriptor, aio_poll may or may not call
 422     * event_ready_cb.  Still, it must not block.  */
 423    event_notifier_set(&data.e);
 424    g_assert(aio_poll(ctx, true));
 425    data.n = 0;
 426
 427    /* An active event notifier forces aio_poll to look at EventNotifiers.  */
 428    event_notifier_init(&dummy.e, false);
 429    set_event_notifier(ctx, &dummy.e, event_ready_cb);
 430
 431    event_notifier_set(&data.e);
 432    g_assert(aio_poll(ctx, false));
 433    g_assert_cmpint(data.n, ==, 1);
 434    g_assert(!aio_poll(ctx, false));
 435    g_assert_cmpint(data.n, ==, 1);
 436
 437    event_notifier_set(&data.e);
 438    g_assert(aio_poll(ctx, false));
 439    g_assert_cmpint(data.n, ==, 2);
 440    g_assert(!aio_poll(ctx, false));
 441    g_assert_cmpint(data.n, ==, 2);
 442
 443    event_notifier_set(&dummy.e);
 444    wait_until_inactive(&dummy);
 445    g_assert_cmpint(data.n, ==, 2);
 446    g_assert_cmpint(dummy.n, ==, 1);
 447    g_assert_cmpint(dummy.active, ==, 0);
 448
 449    set_event_notifier(ctx, &dummy.e, NULL);
 450    event_notifier_cleanup(&dummy.e);
 451
 452    set_event_notifier(ctx, &data.e, NULL);
 453    g_assert(!aio_poll(ctx, false));
 454    g_assert_cmpint(data.n, ==, 2);
 455
 456    event_notifier_cleanup(&data.e);
 457}
 458
 459static void test_timer_schedule(void)
 460{
 461    TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
 462                           .max = 2,
 463                           .clock_type = QEMU_CLOCK_REALTIME };
 464    EventNotifier e;
 465
 466    /* aio_poll will not block to wait for timers to complete unless it has
 467     * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
 468     */
 469    event_notifier_init(&e, false);
 470    set_event_notifier(ctx, &e, dummy_io_handler_read);
 471    aio_poll(ctx, false);
 472
 473    aio_timer_init(ctx, &data.timer, data.clock_type,
 474                   SCALE_NS, timer_test_cb, &data);
 475    timer_mod(&data.timer,
 476              qemu_clock_get_ns(data.clock_type) +
 477              data.ns);
 478
 479    g_assert_cmpint(data.n, ==, 0);
 480
 481    /* timer_mod may well cause an event notifer to have gone off,
 482     * so clear that
 483     */
 484    do {} while (aio_poll(ctx, false));
 485
 486    g_assert(!aio_poll(ctx, false));
 487    g_assert_cmpint(data.n, ==, 0);
 488
 489    g_usleep(1 * G_USEC_PER_SEC);
 490    g_assert_cmpint(data.n, ==, 0);
 491
 492    g_assert(aio_poll(ctx, false));
 493    g_assert_cmpint(data.n, ==, 1);
 494
 495    /* timer_mod called by our callback */
 496    do {} while (aio_poll(ctx, false));
 497
 498    g_assert(!aio_poll(ctx, false));
 499    g_assert_cmpint(data.n, ==, 1);
 500
 501    g_assert(aio_poll(ctx, true));
 502    g_assert_cmpint(data.n, ==, 2);
 503
 504    /* As max is now 2, an event notifier should not have gone off */
 505
 506    g_assert(!aio_poll(ctx, false));
 507    g_assert_cmpint(data.n, ==, 2);
 508
 509    set_event_notifier(ctx, &e, NULL);
 510    event_notifier_cleanup(&e);
 511
 512    timer_del(&data.timer);
 513}
 514
 515/* Now the same tests, using the context as a GSource.  They are
 516 * very similar to the ones above, with g_main_context_iteration
 517 * replacing aio_poll.  However:
 518 * - sometimes both the AioContext and the glib main loop wake
 519 *   themselves up.  Hence, some "g_assert(!aio_poll(ctx, false));"
 520 *   are replaced by "while (g_main_context_iteration(NULL, false));".
 521 * - there is no exact replacement for a blocking wait.
 522 *   "while (g_main_context_iteration(NULL, true)" seems to work,
 523 *   but it is not documented _why_ it works.  For these tests a
 524 *   non-blocking loop like "while (g_main_context_iteration(NULL, false)"
 525 *   works well, and that's what I am using.
 526 */
 527
 528static void test_source_flush(void)
 529{
 530    g_assert(!g_main_context_iteration(NULL, false));
 531    aio_notify(ctx);
 532    while (g_main_context_iteration(NULL, false));
 533    g_assert(!g_main_context_iteration(NULL, false));
 534}
 535
 536static void test_source_bh_schedule(void)
 537{
 538    BHTestData data = { .n = 0 };
 539    data.bh = aio_bh_new(ctx, bh_test_cb, &data);
 540
 541    qemu_bh_schedule(data.bh);
 542    g_assert_cmpint(data.n, ==, 0);
 543
 544    g_assert(g_main_context_iteration(NULL, true));
 545    g_assert_cmpint(data.n, ==, 1);
 546
 547    g_assert(!g_main_context_iteration(NULL, false));
 548    g_assert_cmpint(data.n, ==, 1);
 549    qemu_bh_delete(data.bh);
 550}
 551
 552static void test_source_bh_schedule10(void)
 553{
 554    BHTestData data = { .n = 0, .max = 10 };
 555    data.bh = aio_bh_new(ctx, bh_test_cb, &data);
 556
 557    qemu_bh_schedule(data.bh);
 558    g_assert_cmpint(data.n, ==, 0);
 559
 560    g_assert(g_main_context_iteration(NULL, false));
 561    g_assert_cmpint(data.n, ==, 1);
 562
 563    g_assert(g_main_context_iteration(NULL, true));
 564    g_assert_cmpint(data.n, ==, 2);
 565
 566    while (g_main_context_iteration(NULL, false));
 567    g_assert_cmpint(data.n, ==, 10);
 568
 569    g_assert(!g_main_context_iteration(NULL, false));
 570    g_assert_cmpint(data.n, ==, 10);
 571    qemu_bh_delete(data.bh);
 572}
 573
 574static void test_source_bh_cancel(void)
 575{
 576    BHTestData data = { .n = 0 };
 577    data.bh = aio_bh_new(ctx, bh_test_cb, &data);
 578
 579    qemu_bh_schedule(data.bh);
 580    g_assert_cmpint(data.n, ==, 0);
 581
 582    qemu_bh_cancel(data.bh);
 583    g_assert_cmpint(data.n, ==, 0);
 584
 585    while (g_main_context_iteration(NULL, false));
 586    g_assert_cmpint(data.n, ==, 0);
 587    qemu_bh_delete(data.bh);
 588}
 589
 590static void test_source_bh_delete(void)
 591{
 592    BHTestData data = { .n = 0 };
 593    data.bh = aio_bh_new(ctx, bh_test_cb, &data);
 594
 595    qemu_bh_schedule(data.bh);
 596    g_assert_cmpint(data.n, ==, 0);
 597
 598    qemu_bh_delete(data.bh);
 599    g_assert_cmpint(data.n, ==, 0);
 600
 601    while (g_main_context_iteration(NULL, false));
 602    g_assert_cmpint(data.n, ==, 0);
 603}
 604
 605static void test_source_bh_delete_from_cb(void)
 606{
 607    BHTestData data1 = { .n = 0, .max = 1 };
 608
 609    data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
 610
 611    qemu_bh_schedule(data1.bh);
 612    g_assert_cmpint(data1.n, ==, 0);
 613
 614    g_main_context_iteration(NULL, true);
 615    g_assert_cmpint(data1.n, ==, data1.max);
 616    g_assert(data1.bh == NULL);
 617
 618    assert(g_main_context_iteration(NULL, false));
 619    assert(!g_main_context_iteration(NULL, false));
 620}
 621
 622static void test_source_bh_delete_from_cb_many(void)
 623{
 624    BHTestData data1 = { .n = 0, .max = 1 };
 625    BHTestData data2 = { .n = 0, .max = 3 };
 626    BHTestData data3 = { .n = 0, .max = 2 };
 627    BHTestData data4 = { .n = 0, .max = 4 };
 628
 629    data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1);
 630    data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2);
 631    data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3);
 632    data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4);
 633
 634    qemu_bh_schedule(data1.bh);
 635    qemu_bh_schedule(data2.bh);
 636    qemu_bh_schedule(data3.bh);
 637    qemu_bh_schedule(data4.bh);
 638    g_assert_cmpint(data1.n, ==, 0);
 639    g_assert_cmpint(data2.n, ==, 0);
 640    g_assert_cmpint(data3.n, ==, 0);
 641    g_assert_cmpint(data4.n, ==, 0);
 642
 643    g_assert(g_main_context_iteration(NULL, false));
 644    g_assert_cmpint(data1.n, ==, 1);
 645    g_assert_cmpint(data2.n, ==, 1);
 646    g_assert_cmpint(data3.n, ==, 1);
 647    g_assert_cmpint(data4.n, ==, 1);
 648    g_assert(data1.bh == NULL);
 649
 650    while (g_main_context_iteration(NULL, false));
 651    g_assert_cmpint(data1.n, ==, data1.max);
 652    g_assert_cmpint(data2.n, ==, data2.max);
 653    g_assert_cmpint(data3.n, ==, data3.max);
 654    g_assert_cmpint(data4.n, ==, data4.max);
 655    g_assert(data1.bh == NULL);
 656    g_assert(data2.bh == NULL);
 657    g_assert(data3.bh == NULL);
 658    g_assert(data4.bh == NULL);
 659}
 660
 661static void test_source_bh_flush(void)
 662{
 663    BHTestData data = { .n = 0 };
 664    data.bh = aio_bh_new(ctx, bh_test_cb, &data);
 665
 666    qemu_bh_schedule(data.bh);
 667    g_assert_cmpint(data.n, ==, 0);
 668
 669    g_assert(g_main_context_iteration(NULL, true));
 670    g_assert_cmpint(data.n, ==, 1);
 671
 672    g_assert(!g_main_context_iteration(NULL, false));
 673    g_assert_cmpint(data.n, ==, 1);
 674    qemu_bh_delete(data.bh);
 675}
 676
 677static void test_source_set_event_notifier(void)
 678{
 679    EventNotifierTestData data = { .n = 0, .active = 0 };
 680    event_notifier_init(&data.e, false);
 681    set_event_notifier(ctx, &data.e, event_ready_cb);
 682    while (g_main_context_iteration(NULL, false));
 683    g_assert_cmpint(data.n, ==, 0);
 684
 685    set_event_notifier(ctx, &data.e, NULL);
 686    while (g_main_context_iteration(NULL, false));
 687    g_assert_cmpint(data.n, ==, 0);
 688    event_notifier_cleanup(&data.e);
 689}
 690
 691static void test_source_wait_event_notifier(void)
 692{
 693    EventNotifierTestData data = { .n = 0, .active = 1 };
 694    event_notifier_init(&data.e, false);
 695    set_event_notifier(ctx, &data.e, event_ready_cb);
 696    while (g_main_context_iteration(NULL, false));
 697    g_assert_cmpint(data.n, ==, 0);
 698    g_assert_cmpint(data.active, ==, 1);
 699
 700    event_notifier_set(&data.e);
 701    g_assert(g_main_context_iteration(NULL, false));
 702    g_assert_cmpint(data.n, ==, 1);
 703    g_assert_cmpint(data.active, ==, 0);
 704
 705    while (g_main_context_iteration(NULL, false));
 706    g_assert_cmpint(data.n, ==, 1);
 707    g_assert_cmpint(data.active, ==, 0);
 708
 709    set_event_notifier(ctx, &data.e, NULL);
 710    while (g_main_context_iteration(NULL, false));
 711    g_assert_cmpint(data.n, ==, 1);
 712
 713    event_notifier_cleanup(&data.e);
 714}
 715
 716static void test_source_flush_event_notifier(void)
 717{
 718    EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
 719    event_notifier_init(&data.e, false);
 720    set_event_notifier(ctx, &data.e, event_ready_cb);
 721    while (g_main_context_iteration(NULL, false));
 722    g_assert_cmpint(data.n, ==, 0);
 723    g_assert_cmpint(data.active, ==, 10);
 724
 725    event_notifier_set(&data.e);
 726    g_assert(g_main_context_iteration(NULL, false));
 727    g_assert_cmpint(data.n, ==, 1);
 728    g_assert_cmpint(data.active, ==, 9);
 729    g_assert(g_main_context_iteration(NULL, false));
 730
 731    while (g_main_context_iteration(NULL, false));
 732    g_assert_cmpint(data.n, ==, 10);
 733    g_assert_cmpint(data.active, ==, 0);
 734    g_assert(!g_main_context_iteration(NULL, false));
 735
 736    set_event_notifier(ctx, &data.e, NULL);
 737    while (g_main_context_iteration(NULL, false));
 738    event_notifier_cleanup(&data.e);
 739}
 740
 741static void test_source_wait_event_notifier_noflush(void)
 742{
 743    EventNotifierTestData data = { .n = 0 };
 744    EventNotifierTestData dummy = { .n = 0, .active = 1 };
 745
 746    event_notifier_init(&data.e, false);
 747    set_event_notifier(ctx, &data.e, event_ready_cb);
 748
 749    while (g_main_context_iteration(NULL, false));
 750    g_assert_cmpint(data.n, ==, 0);
 751
 752    /* Until there is an active descriptor, glib may or may not call
 753     * event_ready_cb.  Still, it must not block.  */
 754    event_notifier_set(&data.e);
 755    g_main_context_iteration(NULL, true);
 756    data.n = 0;
 757
 758    /* An active event notifier forces aio_poll to look at EventNotifiers.  */
 759    event_notifier_init(&dummy.e, false);
 760    set_event_notifier(ctx, &dummy.e, event_ready_cb);
 761
 762    event_notifier_set(&data.e);
 763    g_assert(g_main_context_iteration(NULL, false));
 764    g_assert_cmpint(data.n, ==, 1);
 765    g_assert(!g_main_context_iteration(NULL, false));
 766    g_assert_cmpint(data.n, ==, 1);
 767
 768    event_notifier_set(&data.e);
 769    g_assert(g_main_context_iteration(NULL, false));
 770    g_assert_cmpint(data.n, ==, 2);
 771    g_assert(!g_main_context_iteration(NULL, false));
 772    g_assert_cmpint(data.n, ==, 2);
 773
 774    event_notifier_set(&dummy.e);
 775    while (g_main_context_iteration(NULL, false));
 776    g_assert_cmpint(data.n, ==, 2);
 777    g_assert_cmpint(dummy.n, ==, 1);
 778    g_assert_cmpint(dummy.active, ==, 0);
 779
 780    set_event_notifier(ctx, &dummy.e, NULL);
 781    event_notifier_cleanup(&dummy.e);
 782
 783    set_event_notifier(ctx, &data.e, NULL);
 784    while (g_main_context_iteration(NULL, false));
 785    g_assert_cmpint(data.n, ==, 2);
 786
 787    event_notifier_cleanup(&data.e);
 788}
 789
 790static void test_source_timer_schedule(void)
 791{
 792    TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
 793                           .max = 2,
 794                           .clock_type = QEMU_CLOCK_REALTIME };
 795    EventNotifier e;
 796    int64_t expiry;
 797
 798    /* aio_poll will not block to wait for timers to complete unless it has
 799     * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
 800     */
 801    event_notifier_init(&e, false);
 802    set_event_notifier(ctx, &e, dummy_io_handler_read);
 803    do {} while (g_main_context_iteration(NULL, false));
 804
 805    aio_timer_init(ctx, &data.timer, data.clock_type,
 806                   SCALE_NS, timer_test_cb, &data);
 807    expiry = qemu_clock_get_ns(data.clock_type) +
 808        data.ns;
 809    timer_mod(&data.timer, expiry);
 810
 811    g_assert_cmpint(data.n, ==, 0);
 812
 813    g_usleep(1 * G_USEC_PER_SEC);
 814    g_assert_cmpint(data.n, ==, 0);
 815
 816    g_assert(g_main_context_iteration(NULL, true));
 817    g_assert_cmpint(data.n, ==, 1);
 818    expiry += data.ns;
 819
 820    while (data.n < 2) {
 821        g_main_context_iteration(NULL, true);
 822    }
 823
 824    g_assert_cmpint(data.n, ==, 2);
 825    g_assert(qemu_clock_get_ns(data.clock_type) > expiry);
 826
 827    set_event_notifier(ctx, &e, NULL);
 828    event_notifier_cleanup(&e);
 829
 830    timer_del(&data.timer);
 831}
 832
 833/*
 834 * Check that aio_co_enter() can chain many times
 835 *
 836 * Two coroutines should be able to invoke each other via aio_co_enter() many
 837 * times without hitting a limit like stack exhaustion.  In other words, the
 838 * calls should be chained instead of nested.
 839 */
 840
 841typedef struct {
 842    Coroutine *other;
 843    unsigned i;
 844    unsigned max;
 845} ChainData;
 846
 847static void coroutine_fn chain(void *opaque)
 848{
 849    ChainData *data = opaque;
 850
 851    for (data->i = 0; data->i < data->max; data->i++) {
 852        /* Queue up the other coroutine... */
 853        aio_co_enter(ctx, data->other);
 854
 855        /* ...and give control to it */
 856        qemu_coroutine_yield();
 857    }
 858}
 859
 860static void test_queue_chaining(void)
 861{
 862    /* This number of iterations hit stack exhaustion in the past: */
 863    ChainData data_a = { .max = 25000 };
 864    ChainData data_b = { .max = 25000 };
 865
 866    data_b.other = qemu_coroutine_create(chain, &data_a);
 867    data_a.other = qemu_coroutine_create(chain, &data_b);
 868
 869    qemu_coroutine_enter(data_b.other);
 870
 871    g_assert_cmpint(data_a.i, ==, data_a.max);
 872    g_assert_cmpint(data_b.i, ==, data_b.max - 1);
 873
 874    /* Allow the second coroutine to terminate */
 875    qemu_coroutine_enter(data_a.other);
 876
 877    g_assert_cmpint(data_b.i, ==, data_b.max);
 878}
 879
 880static void co_check_current_thread(void *opaque)
 881{
 882    QemuThread *main_thread = opaque;
 883    assert(qemu_thread_is_self(main_thread));
 884}
 885
 886static void *test_aio_co_enter(void *co)
 887{
 888    /*
 889     * qemu_get_current_aio_context() should not to be the main thread
 890     * AioContext, because this is a worker thread that has not taken
 891     * the BQL.  So aio_co_enter will schedule the coroutine in the
 892     * main thread AioContext.
 893     */
 894    aio_co_enter(qemu_get_aio_context(), co);
 895    return NULL;
 896}
 897
 898static void test_worker_thread_co_enter(void)
 899{
 900    QemuThread this_thread, worker_thread;
 901    Coroutine *co;
 902
 903    qemu_thread_get_self(&this_thread);
 904    co = qemu_coroutine_create(co_check_current_thread, &this_thread);
 905
 906    qemu_thread_create(&worker_thread, "test_acquire_thread",
 907                       test_aio_co_enter,
 908                       co, QEMU_THREAD_JOINABLE);
 909
 910    /* Test aio_co_enter from a worker thread.  */
 911    qemu_thread_join(&worker_thread);
 912    g_assert(aio_poll(ctx, true));
 913    g_assert(!aio_poll(ctx, false));
 914}
 915
 916/* End of tests.  */
 917
 918int main(int argc, char **argv)
 919{
 920    qemu_init_main_loop(&error_fatal);
 921    ctx = qemu_get_aio_context();
 922
 923    while (g_main_context_iteration(NULL, false));
 924
 925    g_test_init(&argc, &argv, NULL);
 926    g_test_add_func("/aio/acquire",                 test_acquire);
 927    g_test_add_func("/aio/bh/schedule",             test_bh_schedule);
 928    g_test_add_func("/aio/bh/schedule10",           test_bh_schedule10);
 929    g_test_add_func("/aio/bh/cancel",               test_bh_cancel);
 930    g_test_add_func("/aio/bh/delete",               test_bh_delete);
 931    g_test_add_func("/aio/bh/callback-delete/one",  test_bh_delete_from_cb);
 932    g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many);
 933    g_test_add_func("/aio/bh/flush",                test_bh_flush);
 934    g_test_add_func("/aio/event/add-remove",        test_set_event_notifier);
 935    g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
 936    g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
 937    g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
 938    g_test_add_func("/aio/external-client",         test_aio_external_client);
 939    g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
 940
 941    g_test_add_func("/aio/coroutine/queue-chaining", test_queue_chaining);
 942    g_test_add_func("/aio/coroutine/worker-thread-co-enter", test_worker_thread_co_enter);
 943
 944    g_test_add_func("/aio-gsource/flush",                   test_source_flush);
 945    g_test_add_func("/aio-gsource/bh/schedule",             test_source_bh_schedule);
 946    g_test_add_func("/aio-gsource/bh/schedule10",           test_source_bh_schedule10);
 947    g_test_add_func("/aio-gsource/bh/cancel",               test_source_bh_cancel);
 948    g_test_add_func("/aio-gsource/bh/delete",               test_source_bh_delete);
 949    g_test_add_func("/aio-gsource/bh/callback-delete/one",  test_source_bh_delete_from_cb);
 950    g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many);
 951    g_test_add_func("/aio-gsource/bh/flush",                test_source_bh_flush);
 952    g_test_add_func("/aio-gsource/event/add-remove",        test_source_set_event_notifier);
 953    g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
 954    g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
 955    g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
 956    g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
 957    return g_test_run();
 958}
 959