diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2017-06-12 14:14:42 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2017-06-12 14:14:42 +0100 |
| commit | 2a8469aaabdc86c369bf4aeb77f87de7361f464b (patch) | |
| tree | d8ed3bc0abeb328d50bd303c6617f5a800ea8385 /util/qemu-coroutine-lock.c | |
| parent | 475df9d809b1f3a7ebe8b15abd208216591f0143 (diff) | |
| parent | 11cde1c81093a33c46c7a4039bf750bb61551087 (diff) | |
| download | focaccia-qemu-2a8469aaabdc86c369bf4aeb77f87de7361f464b.tar.gz focaccia-qemu-2a8469aaabdc86c369bf4aeb77f87de7361f464b.zip | |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Wed 07 Jun 2017 19:06:51 BST # gpg: using RSA key 0x9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: configure: split c and cxx extra flags coroutine-lock: do not touch coroutine after another one has been entered .gdbinit: load QEMU sub-commands when gdb starts coccinelle: fix typo in comment oslib: strip trailing '\n' from error_setg() string argument Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/qemu-coroutine-lock.c')
| -rw-r--r-- | util/qemu-coroutine-lock.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c index 6328eed26b..b44b5d55eb 100644 --- a/util/qemu-coroutine-lock.c +++ b/util/qemu-coroutine-lock.c @@ -77,10 +77,25 @@ void coroutine_fn qemu_co_queue_wait(CoQueue *queue, CoMutex *mutex) void qemu_co_queue_run_restart(Coroutine *co) { Coroutine *next; + QSIMPLEQ_HEAD(, Coroutine) tmp_queue_wakeup = + QSIMPLEQ_HEAD_INITIALIZER(tmp_queue_wakeup); trace_qemu_co_queue_run_restart(co); - while ((next = QSIMPLEQ_FIRST(&co->co_queue_wakeup))) { - QSIMPLEQ_REMOVE_HEAD(&co->co_queue_wakeup, co_queue_next); + + /* Because "co" has yielded, any coroutine that we wakeup can resume it. + * If this happens and "co" terminates, co->co_queue_wakeup becomes + * invalid memory. Therefore, use a temporary queue and do not touch + * the "co" coroutine as soon as you enter another one. + * + * In its turn resumed "co" can pupulate "co_queue_wakeup" queue with + * new coroutines to be woken up. The caller, who has resumed "co", + * will be responsible for traversing the same queue, which may cause + * a different wakeup order but not any missing wakeups. + */ + QSIMPLEQ_CONCAT(&tmp_queue_wakeup, &co->co_queue_wakeup); + + while ((next = QSIMPLEQ_FIRST(&tmp_queue_wakeup))) { + QSIMPLEQ_REMOVE_HEAD(&tmp_queue_wakeup, co_queue_next); qemu_coroutine_enter(next); } } |