[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [torsocks/master] Block, rather than busy-wait, in send/recv_data_impl.
commit 3f39f4f0c1ee39116d720282f912303279b02d93
Author: Taylor R Campbell <campbell+torsocks@xxxxxxxxxx>
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 <dgoulet@xxxxxxxxx>
---
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
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits