curl: never invoke callbacks with s->mutex held
All curl callbacks go through curl_multi_do, and hence are called with s->mutex held. Note that with comments, and make curl_read_cb drop the lock before invoking the callback. Likewise for curl_find_buf, where the callback can be invoked by the caller. Cc: qemu-stable@nongnu.org Reviewed-by: Jeff Cody <jcody@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Message-id: 20170515100059.15795-3-pbonzini@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
parent
675a775633
commit
34db05e7ff
12
block/curl.c
12
block/curl.c
@ -148,6 +148,7 @@ static void curl_multi_do(void *arg);
|
||||
static void curl_multi_read(void *arg);
|
||||
|
||||
#ifdef NEED_CURL_TIMER_CALLBACK
|
||||
/* Called from curl_multi_do_locked, with s->mutex held. */
|
||||
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
|
||||
{
|
||||
BDRVCURLState *s = opaque;
|
||||
@ -164,6 +165,7 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Called from curl_multi_do_locked, with s->mutex held. */
|
||||
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
||||
void *userp, void *sp)
|
||||
{
|
||||
@ -213,6 +215,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called from curl_multi_do_locked, with s->mutex held. */
|
||||
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
{
|
||||
BDRVCURLState *s = opaque;
|
||||
@ -227,6 +230,7 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
return realsize;
|
||||
}
|
||||
|
||||
/* Called from curl_multi_do_locked, with s->mutex held. */
|
||||
static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
{
|
||||
CURLState *s = ((CURLState*)opaque);
|
||||
@ -265,7 +269,9 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
request_length - offset);
|
||||
}
|
||||
|
||||
qemu_mutex_unlock(&s->s->mutex);
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
qemu_mutex_lock(&s->s->mutex);
|
||||
qemu_aio_unref(acb);
|
||||
s->acb[i] = NULL;
|
||||
}
|
||||
@ -306,8 +312,6 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
|
||||
if (clamped_len < len) {
|
||||
qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
|
||||
}
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
|
||||
return FIND_RET_OK;
|
||||
}
|
||||
|
||||
@ -854,8 +858,8 @@ static void curl_readv_bh_cb(void *p)
|
||||
// we can just call the callback and be done.
|
||||
switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
|
||||
case FIND_RET_OK:
|
||||
qemu_aio_unref(acb);
|
||||
// fall through
|
||||
ret = 0;
|
||||
goto out;
|
||||
case FIND_RET_WAIT:
|
||||
goto out;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user