diff options
-rw-r--r-- | io.c | 17 | ||||
-rw-r--r-- | thread.c | 19 |
2 files changed, 29 insertions, 7 deletions
@@ -10643,15 +10643,21 @@ maygvl_copy_stream_continue_p(int has_gvl, struct copy_stream_struct *stp) } /* non-Linux poll may not work on all FDs */ -#if defined(HAVE_POLL) && defined(__linux__) -# define USE_POLL 1 -# define IOWAIT_SYSCALL "poll" -#else -# define IOWAIT_SYSCALL "select" +#if defined(HAVE_POLL) +# if defined(__linux__) +# define USE_POLL 1 +# endif +# if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000 +# define USE_POLL 1 +# endif +#endif + +#ifndef USE_POLL # define USE_POLL 0 #endif #if USE_POLL +# define IOWAIT_SYSCALL "poll" STATIC_ASSERT(pollin_expected, POLLIN == RB_WAITFD_IN); STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT); static int @@ -10665,6 +10671,7 @@ nogvl_wait_for_single_fd(int fd, short events) return poll(&fds, 1, -1); } #else /* !USE_POLL */ +# define IOWAIT_SYSCALL "select" static int nogvl_wait_for_single_fd(int fd, short events) { @@ -206,8 +206,15 @@ vm_living_thread_num(const rb_vm_t *vm) * one we know of that supports using poll() in all places select() * would work. */ -#if defined(HAVE_POLL) && defined(__linux__) -# define USE_POLL +#if defined(HAVE_POLL) +# if defined(__linux__) +# define USE_POLL +# endif +# if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000 +# define USE_POLL + /* FreeBSD does not set POLLOUT when POLLHUP happens */ +# define POLLERR_SET (POLLHUP | POLLERR) +# endif #endif static struct timespec * @@ -3923,6 +3930,10 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) #define POLLEX_SET (POLLPRI) +#ifndef POLLERR_SET /* defined for FreeBSD for now */ +# define POLLERR_SET (0) +#endif + #ifndef HAVE_PPOLL /* TODO: don't ignore sigmask */ int @@ -4004,6 +4015,10 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *timeout) if (fds.revents & POLLEX_SET) result |= RB_WAITFD_PRI; + /* all requested events are ready if there is an error */ + if (fds.revents & POLLERR_SET) + result |= events; + return result; } #else /* ! USE_POLL - implement rb_io_poll_fd() using select() */ |