提交 b89d92f3 编写于 作者: S Stefan Hajnoczi

block: add aio_wait_bh_oneshot()

Sometimes it's necessary for the main loop thread to run a BH in an
IOThread and wait for its completion.  This primitive is useful during
startup/shutdown to synchronize and avoid race conditions.
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: NFam Zheng <famz@redhat.com>
Acked-by: NPaolo Bonzini <pbonzini@redhat.com>
Message-id: 20180307144205.20619-2-stefanha@redhat.com
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
上级 12c1c7d7
......@@ -113,4 +113,17 @@ typedef struct {
*/
void aio_wait_kick(AioWait *wait);
/**
* aio_wait_bh_oneshot:
* @ctx: the aio context
* @cb: the BH callback function
* @opaque: user data for the BH callback function
*
* Run a BH in @ctx and wait for it to complete.
*
* Must be called from the main loop thread with @ctx acquired exactly once.
* Note that main loop event processing may occur.
*/
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
#endif /* QEMU_AIO_WAIT */
......@@ -38,3 +38,34 @@ void aio_wait_kick(AioWait *wait)
aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL);
}
}
typedef struct {
AioWait wait;
bool done;
QEMUBHFunc *cb;
void *opaque;
} AioWaitBHData;
/* Context: BH in IOThread */
static void aio_wait_bh(void *opaque)
{
AioWaitBHData *data = opaque;
data->cb(data->opaque);
data->done = true;
aio_wait_kick(&data->wait);
}
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
{
AioWaitBHData data = {
.cb = cb,
.opaque = opaque,
};
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
aio_bh_schedule_oneshot(ctx, aio_wait_bh, &data);
AIO_WAIT_WHILE(&data.wait, ctx, !data.done);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册