]> granicus.if.org Git - curl/commitdiff
curl_multi_wait: fix revents
authorDaniel Stenberg <daniel@haxx.se>
Thu, 18 Jul 2013 21:36:59 +0000 (23:36 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 21 Jul 2013 19:54:47 +0000 (21:54 +0200)
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
lib/multi.c

index dee2356ca67a44fda45cd98885cf0b93716691ba..e173fd64ff81cd93f7c29d3102be5680e9bf507c 100644 (file)
@@ -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;