mirror of https://github.com/xqemu/xqemu.git
block: Allow AIO_WAIT_WHILE with NULL ctx
bdrv_drain_all() wants to have a single polling loop for draining the in-flight requests of all nodes. This means that the AIO_WAIT_WHILE() condition relies on activity in multiple AioContexts, which is polled from the mainloop context. We must therefore call AIO_WAIT_WHILE() from the mainloop thread and use the AioWait notification mechanism. Just randomly picking the AioContext of any non-mainloop thread would work, but instead of bothering to find such a context in the caller, we can just as well accept NULL for ctx. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
57320ca961
commit
4d22bbf4ef
|
@ -57,7 +57,8 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* AIO_WAIT_WHILE:
|
* AIO_WAIT_WHILE:
|
||||||
* @wait: the aio wait object
|
* @wait: the aio wait object
|
||||||
* @ctx: the aio context
|
* @ctx: the aio context, or NULL if multiple aio contexts (for which the
|
||||||
|
* caller does not hold a lock) are involved in the polling condition.
|
||||||
* @cond: wait while this conditional expression is true
|
* @cond: wait while this conditional expression is true
|
||||||
*
|
*
|
||||||
* Wait while a condition is true. Use this to implement synchronous
|
* Wait while a condition is true. Use this to implement synchronous
|
||||||
|
@ -75,7 +76,7 @@ typedef struct {
|
||||||
bool waited_ = false; \
|
bool waited_ = false; \
|
||||||
AioWait *wait_ = (wait); \
|
AioWait *wait_ = (wait); \
|
||||||
AioContext *ctx_ = (ctx); \
|
AioContext *ctx_ = (ctx); \
|
||||||
if (in_aio_context_home_thread(ctx_)) { \
|
if (ctx_ && in_aio_context_home_thread(ctx_)) { \
|
||||||
while ((cond)) { \
|
while ((cond)) { \
|
||||||
aio_poll(ctx_, true); \
|
aio_poll(ctx_, true); \
|
||||||
waited_ = true; \
|
waited_ = true; \
|
||||||
|
@ -86,9 +87,13 @@ typedef struct {
|
||||||
/* Increment wait_->num_waiters before evaluating cond. */ \
|
/* Increment wait_->num_waiters before evaluating cond. */ \
|
||||||
atomic_inc(&wait_->num_waiters); \
|
atomic_inc(&wait_->num_waiters); \
|
||||||
while ((cond)) { \
|
while ((cond)) { \
|
||||||
aio_context_release(ctx_); \
|
if (ctx_) { \
|
||||||
|
aio_context_release(ctx_); \
|
||||||
|
} \
|
||||||
aio_poll(qemu_get_aio_context(), true); \
|
aio_poll(qemu_get_aio_context(), true); \
|
||||||
aio_context_acquire(ctx_); \
|
if (ctx_) { \
|
||||||
|
aio_context_acquire(ctx_); \
|
||||||
|
} \
|
||||||
waited_ = true; \
|
waited_ = true; \
|
||||||
} \
|
} \
|
||||||
atomic_dec(&wait_->num_waiters); \
|
atomic_dec(&wait_->num_waiters); \
|
||||||
|
|
Loading…
Reference in New Issue