gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 25/411: multi: expand pre-check for socket readiness


From: gnunet
Subject: [gnurl] 25/411: multi: expand pre-check for socket readiness
Date: Wed, 13 Jan 2021 01:17:20 +0100

This is an automated email from the git hooks/post-receive script.

nikita pushed a commit to branch master
in repository gnurl.

commit 3334ee6bcb2b23c583f4601dc24d122bb9719f17
Author: Marc Hoersken <info@marc-hoersken.de>
AuthorDate: Sun Jul 26 21:26:46 2020 +0200

    multi: expand pre-check for socket readiness
    
    Check readiness of all sockets before waiting on them
    to avoid locking in case the one-time event FD_WRITE
    was already consumed by a previous wait operation.
    
    More information about WinSock network events:
    https://docs.microsoft.com/en-us/windows/win32/api/
       winsock2/nf-winsock2-wsaeventselect#return-value
    
    Closes #5634
---
 lib/multi.c | 72 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/lib/multi.c b/lib/multi.c
index c8bba47f6..00eb4dd69 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1094,7 +1094,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
   struct pollfd *ufds = &a_few_on_stack[0];
   bool ufds_malloc = FALSE;
 #else
-  int already_writable = 0;
+  struct pollfd pre_poll;
   DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
 #endif
 
@@ -1175,13 +1175,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
     while(data) {
       bitmap = multi_getsock(data, sockbunch);
 
-      for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
         curl_socket_t s = CURL_SOCKET_BAD;
 #ifdef USE_WINSOCK
         long mask = 0;
 #endif
         if(bitmap & GETSOCK_READSOCK(i)) {
 #ifdef USE_WINSOCK
+          if(SOCKET_READABLE(sockbunch[i], 0) > 0)
+            timeout_ms = 0;
           mask |= FD_READ;
 #else
           ufds[nfds].fd = sockbunch[i];
@@ -1192,15 +1194,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
         }
         if(bitmap & GETSOCK_WRITESOCK(i)) {
 #ifdef USE_WINSOCK
-          struct timeval timeout;
-          fd_set writefds;
-          timeout.tv_sec = 0;
-          timeout.tv_usec = 0;
-          FD_ZERO(&writefds);
-          FD_SET(sockbunch[i], &writefds);
-          if(select((int)sockbunch[i] + 1, NULL, &writefds, NULL,
-                    &timeout) == 1)
-            already_writable++;
+          if(SOCKET_WRITABLE(sockbunch[i], 0) > 0)
+            timeout_ms = 0;
           mask |= FD_WRITE;
 #else
           ufds[nfds].fd = sockbunch[i];
@@ -1227,23 +1222,30 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
 #ifdef USE_WINSOCK
     long events = 0;
     extra_fds[i].revents = 0;
-    if(extra_fds[i].events & CURL_WAIT_POLLIN)
+    pre_poll.fd = extra_fds[i].fd;
+    pre_poll.events = 0;
+    pre_poll.revents = 0;
+    if(extra_fds[i].events & CURL_WAIT_POLLIN) {
       events |= FD_READ;
-    if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+      pre_poll.events |= POLLIN;
+    }
+    if(extra_fds[i].events & CURL_WAIT_POLLPRI) {
       events |= FD_OOB;
+      pre_poll.events |= POLLPRI;
+    }
     if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
-      struct timeval timeout;
-      fd_set writefds;
-      timeout.tv_sec = 0;
-      timeout.tv_usec = 0;
-      FD_ZERO(&writefds);
-      FD_SET(extra_fds[i].fd, &writefds);
-      if(select((int)extra_fds[i].fd + 1, NULL, &writefds, NULL,
-                &timeout) == 1) {
-        extra_fds[i].revents = CURL_WAIT_POLLOUT;
-        already_writable++;
-      }
       events |= FD_WRITE;
+      pre_poll.events |= POLLOUT;
+    }
+    if(Curl_poll(&pre_poll, 1, 0) > 0) {
+      if(pre_poll.revents & POLLIN)
+        extra_fds[i].revents |= CURL_WAIT_POLLIN;
+      if(pre_poll.revents & POLLOUT)
+        extra_fds[i].revents |= CURL_WAIT_POLLOUT;
+      if(pre_poll.revents & POLLPRI)
+        extra_fds[i].revents |= CURL_WAIT_POLLPRI;
+      if(extra_fds[i].revents)
+        timeout_ms = 0;
     }
     if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, events) != 0)
       return CURLM_INTERNAL_ERROR;
@@ -1273,8 +1275,6 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
   if(nfds) {
     /* wait... */
 #ifdef USE_WINSOCK
-    if(already_writable > 0)
-      timeout_ms = 0;
     WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
 #else
     int pollrc = Curl_poll(ufds, nfds, timeout_ms);
@@ -1306,7 +1306,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
           if(events.lNetworkEvents & FD_OOB)
             mask |= CURL_WAIT_POLLPRI;
 
-          if(events.lNetworkEvents != 0)
+          if(ret && events.lNetworkEvents != 0)
             retcode++;
         }
         WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
@@ -1337,19 +1337,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
               WSANETWORKEVENTS events = {0};
               if(WSAEnumNetworkEvents(sockbunch[i], multi->wsa_event,
                                       &events) == 0) {
-                if(events.lNetworkEvents != 0)
+                if(ret && events.lNetworkEvents != 0)
                   retcode++;
               }
-              if(ret && !events.lNetworkEvents &&
-                 (bitmap & GETSOCK_WRITESOCK(i))) {
-                struct timeval timeout;
-                fd_set writefds;
-                timeout.tv_sec = 0;
-                timeout.tv_usec = 0;
-                FD_ZERO(&writefds);
-                FD_SET(sockbunch[i], &writefds);
-                if(select((int)sockbunch[i] + 1, NULL, &writefds, NULL,
-                          &timeout) == 1)
+              if(ret && !timeout_ms && !events.lNetworkEvents) {
+                if((bitmap & GETSOCK_READSOCK(i)) &&
+                   SOCKET_READABLE(sockbunch[i], 0) > 0)
+                  retcode++;
+                else if((bitmap & GETSOCK_WRITESOCK(i)) &&
+                   SOCKET_WRITABLE(sockbunch[i], 0) > 0)
                   retcode++;
               }
               WSAEventSelect(sockbunch[i], multi->wsa_event, 0);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]