You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
6.2 KiB
218 lines
6.2 KiB
From 070718b3e00d0341d44dd5ad4b48fd4468d047c6 Mon Sep 17 00:00:00 2001 |
|
From: Daniel Stenberg <daniel@haxx.se> |
|
Date: Sat, 9 Mar 2013 22:26:07 +0100 |
|
Subject: [PATCH 1/3] curl_multi_wait: avoid second loop if nothing to do |
|
|
|
... hopefully this will also make clang-analyzer stop warning on |
|
potentional NULL dereferences (which were false positives anyway). |
|
|
|
Upstream-commit: 136a3a0ee25f28fec1dde216467389f9e6e4f65c |
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com> |
|
--- |
|
lib/multi.c | 55 ++++++++++++++++++++++++++++++++----------------------- |
|
1 file changed, 32 insertions(+), 23 deletions(-) |
|
|
|
diff --git a/lib/multi.c b/lib/multi.c |
|
index 6dfce9b..1136849 100644 |
|
--- a/lib/multi.c |
|
+++ b/lib/multi.c |
|
@@ -804,7 +804,8 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; |
|
int bitmap; |
|
unsigned int i; |
|
- unsigned int nfds = extra_nfds; |
|
+ unsigned int nfds = 0; |
|
+ unsigned int curlfds; |
|
struct pollfd *ufds = NULL; |
|
long timeout_internal; |
|
|
|
@@ -842,6 +843,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
easy = easy->next; /* check next handle */ |
|
} |
|
|
|
+ curlfds = nfds; /* number of internal file descriptors */ |
|
+ nfds += extra_nfds; /* add the externally provided ones */ |
|
+ |
|
if(nfds) { |
|
ufds = malloc(nfds * sizeof(struct pollfd)); |
|
if(!ufds) |
|
@@ -849,32 +853,37 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
} |
|
nfds = 0; |
|
|
|
- /* Add the curl handles to our pollfds first */ |
|
- easy=multi->easy.next; |
|
- while(easy != &multi->easy) { |
|
- bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); |
|
+ /* only do the second loop if we found descriptors in the first stage run |
|
+ above */ |
|
|
|
- for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { |
|
- curl_socket_t s = CURL_SOCKET_BAD; |
|
+ if(curlfds) { |
|
+ /* Add the curl handles to our pollfds first */ |
|
+ easy=multi->easy.next; |
|
+ while(easy != &multi->easy) { |
|
+ bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); |
|
|
|
- if(bitmap & GETSOCK_READSOCK(i)) { |
|
- ufds[nfds].fd = sockbunch[i]; |
|
- ufds[nfds].events = POLLIN; |
|
- ++nfds; |
|
- s = sockbunch[i]; |
|
- } |
|
- if(bitmap & GETSOCK_WRITESOCK(i)) { |
|
- ufds[nfds].fd = sockbunch[i]; |
|
- ufds[nfds].events = POLLOUT; |
|
- ++nfds; |
|
- s = sockbunch[i]; |
|
- } |
|
- if(s == CURL_SOCKET_BAD) { |
|
- break; |
|
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { |
|
+ curl_socket_t s = CURL_SOCKET_BAD; |
|
+ |
|
+ if(bitmap & GETSOCK_READSOCK(i)) { |
|
+ ufds[nfds].fd = sockbunch[i]; |
|
+ ufds[nfds].events = POLLIN; |
|
+ ++nfds; |
|
+ s = sockbunch[i]; |
|
+ } |
|
+ if(bitmap & GETSOCK_WRITESOCK(i)) { |
|
+ ufds[nfds].fd = sockbunch[i]; |
|
+ ufds[nfds].events = POLLOUT; |
|
+ ++nfds; |
|
+ s = sockbunch[i]; |
|
+ } |
|
+ if(s == CURL_SOCKET_BAD) { |
|
+ break; |
|
+ } |
|
} |
|
- } |
|
|
|
- easy = easy->next; /* check next handle */ |
|
+ easy = easy->next; /* check next handle */ |
|
+ } |
|
} |
|
|
|
/* Add external file descriptions from poll-like struct curl_waitfd */ |
|
-- |
|
2.5.5 |
|
|
|
|
|
From f8b84a52088a99d8128c2234f626ed233beabeae Mon Sep 17 00:00:00 2001 |
|
From: Evgeny Turnaev <turnaev.e@gmail.com> |
|
Date: Thu, 18 Jul 2013 00:06:09 +0200 |
|
Subject: [PATCH 2/3] curl_multi_wait: set revents for extra fds |
|
|
|
Pass back the revents that happened for the user-provided file |
|
descriptors. |
|
|
|
Upstream-commit: 6d30f8ebed34e7276c2a59ee20d466bff17fee56 |
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com> |
|
--- |
|
lib/multi.c | 5 ++++- |
|
1 file changed, 4 insertions(+), 1 deletion(-) |
|
|
|
diff --git a/lib/multi.c b/lib/multi.c |
|
index 1136849..81bcfba 100644 |
|
--- a/lib/multi.c |
|
+++ b/lib/multi.c |
|
@@ -803,7 +803,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
struct Curl_one_easy *easy; |
|
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; |
|
int bitmap; |
|
- unsigned int i; |
|
+ unsigned int i, j; |
|
unsigned int nfds = 0; |
|
unsigned int curlfds; |
|
struct pollfd *ufds = NULL; |
|
@@ -905,6 +905,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
else |
|
i = 0; |
|
|
|
+ for(j = nfds - extra_nfds; j < nfds; j++) |
|
+ extra_fds[j].revents = ufds[j].revents; |
|
+ |
|
Curl_safefree(ufds); |
|
if(ret) |
|
*ret = i; |
|
-- |
|
2.5.5 |
|
|
|
|
|
From db2e5b5ffe5408aa892dee9e7f036fe0ea16963d Mon Sep 17 00:00:00 2001 |
|
From: Daniel Stenberg <daniel@haxx.se> |
|
Date: Thu, 18 Jul 2013 23:36:59 +0200 |
|
Subject: [PATCH 3/3] curl_multi_wait: fix revents |
|
|
|
Commit 6d30f8ebed34e7276 didn't work properly. First, it used the wrong |
|
array index, but this fix also: |
|
|
|
1 - only does the copying if indeed there was any activity |
|
|
|
2 - makes sure to properly translate between internal and external |
|
bitfields, which are not guaranteed to match |
|
|
|
Reported-by: Evgeny Turnaev |
|
|
|
Upstream-commit: 513e587c5eb966038731530c8f47fe0cf27513ce |
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com> |
|
--- |
|
lib/multi.c | 28 +++++++++++++++++++++++----- |
|
1 file changed, 23 insertions(+), 5 deletions(-) |
|
|
|
diff --git a/lib/multi.c b/lib/multi.c |
|
index 81bcfba..0e0bb19 100644 |
|
--- a/lib/multi.c |
|
+++ b/lib/multi.c |
|
@@ -803,7 +803,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
struct Curl_one_easy *easy; |
|
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; |
|
int bitmap; |
|
- unsigned int i, j; |
|
+ unsigned int i; |
|
unsigned int nfds = 0; |
|
unsigned int curlfds; |
|
struct pollfd *ufds = NULL; |
|
@@ -899,15 +899,33 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, |
|
++nfds; |
|
} |
|
|
|
- if(nfds) |
|
+ if(nfds) { |
|
/* wait... */ |
|
i = Curl_poll(ufds, nfds, timeout_ms); |
|
+ |
|
+ if(i) { |
|
+ unsigned int j; |
|
+ /* copy revents results from the poll to the curl_multi_wait poll |
|
+ struct, the bit values of the actual underlying poll() implementation |
|
+ may not be the same as the ones in the public libcurl API! */ |
|
+ for(j = 0; j < extra_nfds; j++) { |
|
+ unsigned short mask = 0; |
|
+ unsigned r = ufds[curlfds + j].revents; |
|
+ |
|
+ if(r & POLLIN) |
|
+ mask |= CURL_WAIT_POLLIN; |
|
+ if(r & POLLOUT) |
|
+ mask |= CURL_WAIT_POLLOUT; |
|
+ if(r & POLLPRI) |
|
+ mask |= CURL_WAIT_POLLPRI; |
|
+ |
|
+ extra_fds[j].revents = mask; |
|
+ } |
|
+ } |
|
+ } |
|
else |
|
i = 0; |
|
|
|
- for(j = nfds - extra_nfds; j < nfds; j++) |
|
- extra_fds[j].revents = ufds[j].revents; |
|
- |
|
Curl_safefree(ufds); |
|
if(ret) |
|
*ret = i; |
|
-- |
|
2.5.5 |
|
|
|
|