From 148aebdbb1613d250caf378f3484cb4e1c47f3aa Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sun, 8 Mar 2015 16:39:48 -0500 Subject: [PATCH] fix hangs reading stdin on Windows --- apps/poll_win.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/apps/poll_win.c b/apps/poll_win.c index bf30ccf..ce47b01 100644 --- a/apps/poll_win.c +++ b/apps/poll_win.c @@ -44,6 +44,8 @@ conn_has_oob_data(int fd) static int is_socket(int fd) { + if (fd < 3) + return 0; WSANETWORKEVENTS events; return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0); } @@ -160,10 +162,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) nfds_t i; int timespent_ms, looptime_ms; -#define FD_IS_SOCKET (1 << 0) - int fd_state[FD_SETSIZE]; - int num_fds; - /* * select machinery */ @@ -190,14 +188,12 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); - num_fds = 0; num_sockets = 0; num_handles = 0; for (i = 0; i < nfds; i++) { - if ((int)pfds[i].fd < 0) { + if ((int)pfds[i].fd < 0) continue; - } if (is_socket(pfds[i].fd)) { if (num_sockets >= FD_SETSIZE) { @@ -205,8 +201,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) return -1; } - fd_state[num_fds] = FD_IS_SOCKET; - FD_SET(pfds[i].fd, &efds); if (pfds[i].events & @@ -229,8 +223,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) handles[num_handles++] = (HANDLE)_get_osfhandle(pfds[i].fd); } - - num_fds++; } /* @@ -254,21 +246,22 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) * than simply triggering if there is space available. */ timespent_ms = 0; - wait_rc = 0; + wait_rc = WAIT_FAILED; - if (timeout_ms < 0) { + if (timeout_ms < 0) timeout_ms = INFINITE; - } looptime_ms = timeout_ms > 100 ? 100 : timeout_ms; do { struct timeval tv = {0, looptime_ms * 1000}; + int handle_signaled = 0; /* * Check if any file handles have signaled */ if (num_handles) { - wait_rc = WaitForMultipleObjects(num_handles, handles, FALSE, 0); + wait_rc = WaitForMultipleObjects(num_handles, handles, + FALSE, 0); if (wait_rc == WAIT_FAILED) { /* * The documentation for WaitForMultipleObjects @@ -285,18 +278,20 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) /* * If we signaled on a file handle, don't wait on the sockets. */ - if (wait_rc >= WAIT_OBJECT_0) + if (wait_rc >= WAIT_OBJECT_0 && + (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { tv.tv_usec = 0; + handle_signaled = 1; + } /* * Check if any sockets have signaled */ rc = select(0, &rfds, &wfds, &efds, &tv); - if (rc == SOCKET_ERROR) { + if (!handle_signaled && rc == SOCKET_ERROR) return wsa_select_errno(WSAGetLastError()); - } - if (wait_rc >= WAIT_OBJECT_0 || (num_sockets && rc > 0)) + if (handle_signaled || (num_sockets && rc > 0)) break; timespent_ms += looptime_ms; @@ -305,14 +300,14 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) rc = 0; num_handles = 0; - num_fds = 0; for (i = 0; i < nfds; i++) { pfds[i].revents = 0; if ((int)pfds[i].fd < 0) continue; - if (fd_state[num_fds] & FD_IS_SOCKET) { + if (is_socket(pfds[i].fd)) { + pfds[i].revents = compute_select_revents(pfds[i].fd, pfds[i].events, &rfds, &wfds, &efds); @@ -323,8 +318,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) num_handles++; } - num_fds++; - if (pfds[i].revents) rc++; }