diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-03-15 11:53:01 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-03-15 12:16:17 -0400 |
commit | 44514058b96440eaa1b364b915860ae372207ca6 (patch) | |
tree | 02f31e95825f97581fe7775935eecf8432f4412d /src/common/workqueue.c | |
parent | d642ceb8dff5e837bc0e27f9f50812beece06401 (diff) | |
download | tor-44514058b96440eaa1b364b915860ae372207ca6.tar.gz tor-44514058b96440eaa1b364b915860ae372207ca6.zip |
Correctly handle fd-drain errors on windows workqueues
Windows doesn't let you check the socket error for a socket with
WSAGetLastError() and getsockopt(SO_ERROR). But
getsockopt(SO_ERROR) clears the error on the socket, so you can't
call it more than once per error.
When we introduced recv_ni to help drain alert sockets, back in
0.2.6.3-alpha, we had the failure path for recv_ni call getsockopt()
twice, though: once to check for EINTR and one to check for EAGAIN.
Of course, we never got the eagain, so we treated it as an error,
and warned about: "No error".
The fix here is to have these functions return -errno on failure.
Fixes bug 21540; bugfix on 0.2.6.3-alpha.
Diffstat (limited to 'src/common/workqueue.c')
-rw-r--r-- | src/common/workqueue.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/common/workqueue.c b/src/common/workqueue.c index e1fb663a2a..ec6e257b4c 100644 --- a/src/common/workqueue.c +++ b/src/common/workqueue.c @@ -510,12 +510,13 @@ replyqueue_get_socket(replyqueue_t *rq) void replyqueue_process(replyqueue_t *queue) { - if (queue->alert.drain_fn(queue->alert.read_fd) < 0) { + int r = queue->alert.drain_fn(queue->alert.read_fd); + if (r < 0) { //LCOV_EXCL_START static ratelim_t warn_limit = RATELIM_INIT(7200); log_fn_ratelim(&warn_limit, LOG_WARN, LD_GENERAL, "Failure from drain_fd: %s", - tor_socket_strerror(tor_socket_errno(queue->alert.read_fd))); + tor_socket_strerror(-r)); //LCOV_EXCL_STOP } |