summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io.c17
-rw-r--r--thread.c19
2 files changed, 29 insertions, 7 deletions
diff --git a/io.c b/io.c
index 4c724e6166..4c01726c4c 100644
--- a/io.c
+++ b/io.c
@@ -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)
{
diff --git a/thread.c b/thread.c
index 70338bff38..65872971cb 100644
--- a/thread.c
+++ b/thread.c
@@ -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() */