Skip to content

Commit

Permalink
block: add aio_wait_bh_oneshot()
Browse files Browse the repository at this point in the history
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: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20180307144205.20619-2-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Mar 8, 2018
1 parent 12c1c7d commit b89d92f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/block/aio-wait.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
31 changes: 31 additions & 0 deletions util/aio-wait.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit b89d92f

Please sign in to comment.