summaryrefslogtreecommitdiff
path: root/ext/io/wait/wait.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/io/wait/wait.c')
-rw-r--r--ext/io/wait/wait.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/ext/io/wait/wait.c b/ext/io/wait/wait.c
index df8d24c29b..fcb3bcfe42 100644
--- a/ext/io/wait/wait.c
+++ b/ext/io/wait/wait.c
@@ -50,6 +50,23 @@ io_ready_p(io)
return Qnil;
}
+struct wait_readable_arg {
+ rb_fdset_t fds;
+ struct timeval *timeout;
+};
+
+#ifdef HAVE_RB_FD_INIT
+static VALUE
+wait_readable(p)
+ VALUE p;
+{
+ struct wait_readable_arg *arg = (struct wait_readable_arg *)p;
+ rb_fdset_t *fds = &arg->fds;
+
+ return (VALUE)rb_thread_select(rb_fd_max(fds), rb_fd_ptr(fds), NULL, NULL, arg->timeout);
+}
+#endif
+
/*
=begin
--- IO#wait([timeout])
@@ -64,27 +81,33 @@ io_wait(argc, argv, io)
VALUE io;
{
OpenFile *fptr;
- fd_set rd;
+ struct wait_readable_arg arg;
int fd, n;
VALUE timeout;
- struct timeval *tp, timerec;
+ struct timeval timerec;
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
rb_scan_args(argc, argv, "01", &timeout);
if (NIL_P(timeout)) {
- tp = 0;
+ arg.timeout = 0;
}
else {
timerec = rb_time_interval(timeout);
- tp = &timerec;
+ arg.timeout = &timerec;
}
if (rb_io_read_pending(fptr)) return Qtrue;
fd = fptr->fd;
- FD_ZERO(&rd);
- FD_SET(fd, &rd);
- if (rb_thread_select(fd + 1, &rd, NULL, NULL, tp) < 0)
+ rb_fd_init(&arg.fds);
+ rb_fd_set(fd, &arg.fds);
+#ifdef HAVE_RB_FD_INIT
+ n = (int)rb_ensure(wait_readable, (VALUE)&arg,
+ (VALUE (*)_((VALUE)))rb_fd_term, (VALUE)&arg.fds);
+#else
+ n = rb_thread_select(fd + 1, rb_fd_ptr(&rd), NULL, NULL, tp)
+#endif
+ if (n < 0)
rb_sys_fail(0);
rb_io_check_closed(fptr);
if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);