diff mbox

block/curl: wake read completion coroutine only if necessary

Message ID 1503676346-3762-1-git-send-email-wrfsh@yandex-team.ru (mailing list archive)
State New, archived
Headers show

Commit Message

Evgeny Yakovlev Aug. 25, 2017, 3:52 p.m. UTC
When curl_co_preadv is called it sets up an ACB block which points to
current coroutine. It will then call curl_setup_preadv and wait until
request is completed by polling return status and yeilding:

    curl_setup_preadv(bs, &acb);
    while (acb.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

curl_setup_preadv will ask libcurl to handle read request and to use
curl_read_cb as completion callback for each completed chunk.

When curl_read_cb sees request as completed it will attempt to wake up
issuing coroutine assuming that yield was called previously:

    qemu_mutex_unlock(&s->s->mutex);
    aio_co_wake(acb->co);
    qemu_mutex_lock(&s->s->mutex);

However if request is short enough (< 16K in our test) curl_read_cb will
be called right away before returning from libcurl to curl_setup_preadv.
Request will be completed before yield was called from the same
coroutine, which asserts in aio_co_enter.

This change attempts to fix this by waking completion coroutine only if
it is not the current one.

Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
---
 block/curl.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/block/curl.c b/block/curl.c
index 2a244e2..b1106d6 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -271,9 +271,12 @@  static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
 
             acb->ret = 0;
             s->acb[i] = NULL;
-            qemu_mutex_unlock(&s->s->mutex);
-            aio_co_wake(acb->co);
-            qemu_mutex_lock(&s->s->mutex);
+
+            if (qemu_coroutine_self() != acb->co) {
+                qemu_mutex_unlock(&s->s->mutex);
+                aio_co_wake(acb->co);
+                qemu_mutex_lock(&s->s->mutex);
+            }
         }
     }