diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2022-04-27 15:08:28 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-05-12 12:29:44 +0200 |
commit | 248af9e80a04c5ab4ffec789aa24345d3d86b42b (patch) | |
tree | 3f1fbd4ff264301762319ef3d0413dae224e8b17 /util/qemu-coroutine-lock.c | |
parent | bf2f69d08bf158bfdbbe251357452f9576489b6d (diff) |
coroutine-lock: qemu_co_queue_next is a coroutine-only qemu_co_enter_next
qemu_co_queue_next is basically the same as qemu_co_enter_next but
without a QemuLockable argument. That's perfectly fine, but only
as long as the function is marked coroutine_fn. If used outside
coroutine context, qemu_co_queue_wait will attempt to take the lock
and that is just broken: if you are calling qemu_co_queue_next outside
coroutine context, the lock is going to be a QemuMutex which cannot be
taken twice by the same thread.
The patch adds the marker and reimplements qemu_co_queue_next in terms of
qemu_co_enter_next_impl, to remove duplicated code and to clarify that the
latter also works in coroutine context.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20220427130830.150180-2-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'util/qemu-coroutine-lock.c')
-rw-r--r-- | util/qemu-coroutine-lock.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c index 2669403839..5705cfea2e 100644 --- a/util/qemu-coroutine-lock.c +++ b/util/qemu-coroutine-lock.c @@ -67,7 +67,7 @@ void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock) } } -static bool qemu_co_queue_do_restart(CoQueue *queue, bool single) +void qemu_co_queue_restart_all(CoQueue *queue) { Coroutine *next; @@ -78,23 +78,10 @@ static bool qemu_co_queue_do_restart(CoQueue *queue, bool single) while ((next = QSIMPLEQ_FIRST(&queue->entries)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next); aio_co_wake(next); - if (single) { - break; - } } return true; } -bool qemu_co_queue_next(CoQueue *queue) -{ - return qemu_co_queue_do_restart(queue, true); -} - -void qemu_co_queue_restart_all(CoQueue *queue) -{ - qemu_co_queue_do_restart(queue, false); -} - bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock) { Coroutine *next; @@ -115,6 +102,12 @@ bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock) return true; } +bool coroutine_fn qemu_co_queue_next(CoQueue *queue) +{ + /* No unlock/lock needed in coroutine context. */ + return qemu_co_enter_next_impl(queue, NULL); +} + bool qemu_co_queue_empty(CoQueue *queue) { return QSIMPLEQ_FIRST(&queue->entries) == NULL; |