9ae3a8
From 2b07b0558685c234fd93214be705a4feb058e27b Mon Sep 17 00:00:00 2001
9ae3a8
From: Richard Jones <rjones@redhat.com>
9ae3a8
Date: Thu, 11 Jun 2015 11:40:16 +0200
9ae3a8
Subject: [PATCH 16/30] curl: Eliminate unnecessary use of
9ae3a8
 curl_multi_socket_all
9ae3a8
9ae3a8
Message-id: <1434022828-13037-10-git-send-email-rjones@redhat.com>
9ae3a8
Patchwork-id: 65844
9ae3a8
O-Subject: [RHEL-7.2 qemu-kvm v3 PATCH 09/21] curl: Eliminate unnecessary use of curl_multi_socket_all
9ae3a8
Bugzilla: 1226684
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
9ae3a8
From: Matthew Booth <mbooth@redhat.com>
9ae3a8
9ae3a8
curl_multi_socket_all is a deprecated catch-all which checks for
9ae3a8
activities on all open curl sockets. We have enough information from
9ae3a8
the event loop to check only the sockets with activity. This change
9ae3a8
removes use of curl_multi_socket_all in favour of
9ae3a8
curl_multi_socket_action called with the relevant handle.
9ae3a8
9ae3a8
At the same time, it also ensures that the driver only checks for
9ae3a8
completion of read operations after reading from a socket, rather than
9ae3a8
both reading and writing.
9ae3a8
9ae3a8
Signed-off-by: Matthew Booth <mbooth@redhat.com>
9ae3a8
Tested-by: Richard W.M. Jones <rjones@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
9ae3a8
Upstream-status: 838ef602498b8d1985a231a06f5e328e2946a81d
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/curl.c | 34 +++++++++++++++++++++++-----------
9ae3a8
 1 file changed, 23 insertions(+), 11 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/curl.c b/block/curl.c
9ae3a8
index e4332c5..b19e632 100644
9ae3a8
--- a/block/curl.c
9ae3a8
+++ b/block/curl.c
9ae3a8
@@ -71,6 +71,7 @@ typedef struct CURLState
9ae3a8
     struct BDRVCURLState *s;
9ae3a8
     CURLAIOCB *acb[CURL_NUM_ACB];
9ae3a8
     CURL *curl;
9ae3a8
+    curl_socket_t sock_fd;
9ae3a8
     char *orig_buf;
9ae3a8
     size_t buf_start;
9ae3a8
     size_t buf_off;
9ae3a8
@@ -92,6 +93,7 @@ typedef struct BDRVCURLState {
9ae3a8
 static void curl_clean_state(CURLState *s);
9ae3a8
 static void curl_multi_do(void *arg);
9ae3a8
 static int curl_aio_flush(void *opaque);
9ae3a8
+static void curl_multi_read(void *arg);
9ae3a8
 
9ae3a8
 #ifdef NEED_CURL_TIMER_CALLBACK
9ae3a8
 static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
9ae3a8
@@ -113,17 +115,21 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
9ae3a8
 static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
9ae3a8
                         void *s, void *sp)
9ae3a8
 {
9ae3a8
+    CURLState *state = NULL;
9ae3a8
+    curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
9ae3a8
+    state->sock_fd = fd;
9ae3a8
+
9ae3a8
     DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
9ae3a8
     switch (action) {
9ae3a8
         case CURL_POLL_IN:
9ae3a8
-            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, curl_aio_flush, s);
9ae3a8
+            qemu_aio_set_fd_handler(fd, curl_multi_read, NULL, curl_aio_flush, state);
9ae3a8
             break;
9ae3a8
         case CURL_POLL_OUT:
9ae3a8
-            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, curl_aio_flush, s);
9ae3a8
+            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, curl_aio_flush, state);
9ae3a8
             break;
9ae3a8
         case CURL_POLL_INOUT:
9ae3a8
-            qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do,
9ae3a8
-                                    curl_aio_flush, s);
9ae3a8
+            qemu_aio_set_fd_handler(fd, curl_multi_read, curl_multi_do,
9ae3a8
+                                    curl_aio_flush, state);
9ae3a8
             break;
9ae3a8
         case CURL_POLL_REMOVE:
9ae3a8
             qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL);
9ae3a8
@@ -236,7 +242,7 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
9ae3a8
     return FIND_RET_NONE;
9ae3a8
 }
9ae3a8
 
9ae3a8
-static void curl_multi_read(BDRVCURLState *s)
9ae3a8
+static void curl_multi_check_completion(BDRVCURLState *s)
9ae3a8
 {
9ae3a8
     int msgs_in_queue;
9ae3a8
 
9ae3a8
@@ -286,19 +292,26 @@ static void curl_multi_read(BDRVCURLState *s)
9ae3a8
 
9ae3a8
 static void curl_multi_do(void *arg)
9ae3a8
 {
9ae3a8
-    BDRVCURLState *s = (BDRVCURLState *)arg;
9ae3a8
+    CURLState *s = (CURLState *)arg;
9ae3a8
     int running;
9ae3a8
     int r;
9ae3a8
 
9ae3a8
-    if (!s->multi) {
9ae3a8
+    if (!s->s->multi) {
9ae3a8
         return;
9ae3a8
     }
9ae3a8
 
9ae3a8
     do {
9ae3a8
-        r = curl_multi_socket_all(s->multi, &running);
9ae3a8
+        r = curl_multi_socket_action(s->s->multi, s->sock_fd, 0, &running);
9ae3a8
     } while(r == CURLM_CALL_MULTI_PERFORM);
9ae3a8
 
9ae3a8
-    curl_multi_read(s);
9ae3a8
+}
9ae3a8
+
9ae3a8
+static void curl_multi_read(void *arg)
9ae3a8
+{
9ae3a8
+    CURLState *s = (CURLState *)arg;
9ae3a8
+
9ae3a8
+    curl_multi_do(arg);
9ae3a8
+    curl_multi_check_completion(s->s);
9ae3a8
 }
9ae3a8
 
9ae3a8
 static void curl_multi_timeout_do(void *arg)
9ae3a8
@@ -313,7 +326,7 @@ static void curl_multi_timeout_do(void *arg)
9ae3a8
 
9ae3a8
     curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
9ae3a8
 
9ae3a8
-    curl_multi_read(s);
9ae3a8
+    curl_multi_check_completion(s);
9ae3a8
 #else
9ae3a8
     abort();
9ae3a8
 #endif
9ae3a8
@@ -517,7 +530,6 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
     // initialize the multi interface!
9ae3a8
 
9ae3a8
     s->multi = curl_multi_init();
9ae3a8
-    curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
9ae3a8
     curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
9ae3a8
 #ifdef NEED_CURL_TIMER_CALLBACK
9ae3a8
     curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8