aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2013-07-18 23:36:59 +0200
committerDaniel Stenberg <daniel@haxx.se>2013-07-21 21:54:47 +0200
commit513e587c5eb966038731530c8f47fe0cf27513ce (patch)
treed2a9f43cdc26d6aef3db51f4f501fce56805fa68
parent6ed2bcc5f5635961de57bd80199d6a3e3983ef3f (diff)
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
-rw-r--r--lib/multi.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/multi.c b/lib/multi.c
index dee2356ca..e173fd64f 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -808,7 +808,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;
@@ -904,15 +904,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;