commit 3f39f4f0c1ee39116d720282f912303279b02d93
Author: Taylor R Campbell <[email protected]>
Date:   Mon Jun 13 15:56:49 2016 -0400

    Block, rather than busy-wait, in send/recv_data_impl.
    
    The send_data_impl and recv_data_impl functions can enter an annoying busy
    loop if a connection is laggy. Potentially if the connection never
    establishes, this can continue for minutes, until the connection times out,
    having at least one core running at 100% the entire time, which is
    undesirable.
    
    Block on the fd until an I/O operation can be performed.
    
    Fixes #16355
    
    Signed-off-by: David Goulet <[email protected]>
---
 src/common/socks5.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/src/common/socks5.c b/src/common/socks5.c
index 6d58f4d..962a968 100644
--- a/src/common/socks5.c
+++ b/src/common/socks5.c
@@ -26,6 +26,23 @@
 #include "log.h"
 #include "socks5.h"
 
+/* Wait on the given fd for data to become available or any I/O event. Return
+ * 1 on success else a negative errno. */
+static int
+wait_on_fd(int fd)
+{
+       /* By default, fd is ready unless select fails. */
+       int ret = 1;
+       fd_set readfds;
+
+       FD_ZERO(&readfds);
+       FD_SET(fd, &readfds);
+       if (select(fd + 1, &readfds, NULL, NULL, NULL) < 0) {
+               ret = -errno;
+       }
+       return ret;
+}
+
 /*
  * Receive data on a given file descriptor using recv(2). This handles partial
  * send and EINTR.
@@ -49,12 +66,8 @@ static ssize_t recv_data_impl(int fd, void *buf, size_t len)
                                /* Try again after interruption. */
                                continue;
                        } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                               /* Wait for data to become available */
-                               fd_set readfds;
-                               FD_ZERO(&readfds);
-                               FD_SET(fd, &readfds);
-                               if (select(fd + 1, &readfds, NULL, NULL, NULL) 
< 0) {
-                                       ret = -errno;
+                               ret = wait_on_fd(fd);
+                               if (ret < 0) {
                                        goto error;
                                }
                                continue;
@@ -106,12 +119,8 @@ static ssize_t send_data_impl(int fd, const void *buf, 
size_t len)
                                /* Send again after interruption. */
                                continue;
                        } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                               /* Wait for buffer space to become available */
-                               fd_set writefds;
-                               FD_ZERO(&writefds);
-                               FD_SET(fd, &writefds);
-                               if (select(fd + 1, NULL, &writefds, NULL, NULL) 
< 0) {
-                                       ret = -errno;
+                               ret = wait_on_fd(fd);
+                               if (ret < 0) {
                                        goto error;
                                }
                                continue;



_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to