qemu/tests/iothread.c
<<
>>
Prefs
   1/*
   2 * Event loop thread implementation for unit tests
   3 *
   4 * Copyright Red Hat Inc., 2013, 2016
   5 *
   6 * Authors:
   7 *  Stefan Hajnoczi   <stefanha@redhat.com>
   8 *  Paolo Bonzini     <pbonzini@redhat.com>
   9 *
  10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  11 * See the COPYING file in the top-level directory.
  12 *
  13 */
  14
  15#include "qemu/osdep.h"
  16#include "qapi/error.h"
  17#include "block/aio.h"
  18#include "qemu/main-loop.h"
  19#include "qemu/rcu.h"
  20#include "iothread.h"
  21
  22struct IOThread {
  23    AioContext *ctx;
  24
  25    QemuThread thread;
  26    QemuMutex init_done_lock;
  27    QemuCond init_done_cond;    /* is thread initialization done? */
  28    bool stopping;
  29};
  30
  31static __thread IOThread *my_iothread;
  32
  33AioContext *qemu_get_current_aio_context(void)
  34{
  35    return my_iothread ? my_iothread->ctx : qemu_get_aio_context();
  36}
  37
  38static void *iothread_run(void *opaque)
  39{
  40    IOThread *iothread = opaque;
  41
  42    rcu_register_thread();
  43
  44    my_iothread = iothread;
  45    qemu_mutex_lock(&iothread->init_done_lock);
  46    iothread->ctx = aio_context_new(&error_abort);
  47    qemu_cond_signal(&iothread->init_done_cond);
  48    qemu_mutex_unlock(&iothread->init_done_lock);
  49
  50    while (!atomic_read(&iothread->stopping)) {
  51        aio_poll(iothread->ctx, true);
  52    }
  53
  54    rcu_unregister_thread();
  55    return NULL;
  56}
  57
  58void iothread_join(IOThread *iothread)
  59{
  60    iothread->stopping = true;
  61    aio_notify(iothread->ctx);
  62    qemu_thread_join(&iothread->thread);
  63    qemu_cond_destroy(&iothread->init_done_cond);
  64    qemu_mutex_destroy(&iothread->init_done_lock);
  65    aio_context_unref(iothread->ctx);
  66    g_free(iothread);
  67}
  68
  69IOThread *iothread_new(void)
  70{
  71    IOThread *iothread = g_new0(IOThread, 1);
  72
  73    qemu_mutex_init(&iothread->init_done_lock);
  74    qemu_cond_init(&iothread->init_done_cond);
  75    qemu_thread_create(&iothread->thread, NULL, iothread_run,
  76                       iothread, QEMU_THREAD_JOINABLE);
  77
  78    /* Wait for initialization to complete */
  79    qemu_mutex_lock(&iothread->init_done_lock);
  80    while (iothread->ctx == NULL) {
  81        qemu_cond_wait(&iothread->init_done_cond,
  82                       &iothread->init_done_lock);
  83    }
  84    qemu_mutex_unlock(&iothread->init_done_lock);
  85    return iothread;
  86}
  87
  88AioContext *iothread_get_aio_context(IOThread *iothread)
  89{
  90    return iothread->ctx;
  91}
  92