Commit f46369b8 authored by Simon Marlow's avatar Simon Marlow Committed by Ben Gamari
Browse files

fdReady: use poll() instead of select()

select() is limited to 1024 file descriptors.  This actually blew up
in a very hard-to-debug way in our production system when using the
hinotify package.

Test Plan:
libraries/tests pass, paricularly hGetBuf001 which exercises this
code.

Reviewers: niteria, erikd, austin, hvr, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2785

GHC Trac Issues: #12912
parent 27731f14
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
/* select and supporting types is not Posix */ /* select and supporting types is not Posix */
/* #include "PosixSource.h" */ /* #include "PosixSource.h" */
#include "HsBase.h" #include "HsBase.h"
#if !defined(_WIN32)
#include <poll.h>
#endif
/* /*
* inputReady(fd) checks to see whether input is available on the file * inputReady(fd) checks to see whether input is available on the file
...@@ -16,19 +19,41 @@ ...@@ -16,19 +19,41 @@
int int
fdReady(int fd, int write, int msecs, int isSock) fdReady(int fd, int write, int msecs, int isSock)
{ {
if
#if defined(_WIN32) #if !defined(_WIN32)
( isSock ) {
// We only handle msecs == 0 on non-Windows, because this is the
// only case we need. Non-zero waiting is handled by the IO manager.
if (msecs != 0) {
fprintf(stderr, "fdReady: msecs != 0, this shouldn't happen");
abort();
}
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = write ? POLLOUT : POLLIN;
fds[0].revents = 0;
int res;
while ((res = poll(fds, 1, 0)) < 0) {
if (errno != EINTR) {
return (-1);
}
}
// res is the number of FDs with events
return (res > 0);
#else #else
( 1 ) {
#endif if (isSock) {
int maxfd, ready; int maxfd, ready;
fd_set rfd, wfd; fd_set rfd, wfd;
struct timeval tv; struct timeval tv;
if ((fd >= (int)FD_SETSIZE) || (fd < 0)) { if ((fd >= (int)FD_SETSIZE) || (fd < 0)) {
/* avoid memory corruption on too large FDs */ fprintf(stderr, "fdReady: fd is too big");
errno = EINVAL; abort();
return -1;
} }
FD_ZERO(&rfd); FD_ZERO(&rfd);
FD_ZERO(&wfd); FD_ZERO(&wfd);
...@@ -54,7 +79,6 @@ fdReady(int fd, int write, int msecs, int isSock) ...@@ -54,7 +79,6 @@ fdReady(int fd, int write, int msecs, int isSock)
/* 1 => Input ready, 0 => not ready, -1 => error */ /* 1 => Input ready, 0 => not ready, -1 => error */
return (ready); return (ready);
} }
#if defined(_WIN32)
else { else {
DWORD rc; DWORD rc;
HANDLE hFile = (HANDLE)_get_osfhandle(fd); HANDLE hFile = (HANDLE)_get_osfhandle(fd);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment