ext/io/wait/wait.c in io-wait-0.2.0 vs ext/io/wait/wait.c in io-wait-0.2.1
- old
+ new
@@ -38,10 +38,41 @@
#define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd)
#else
#define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
#endif
+#ifndef HAVE_RB_IO_WAIT
+static VALUE io_ready_p _((VALUE io));
+static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io));
+static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io));
+void Init_wait _((void));
+
+static struct timeval *
+get_timeout(int argc, VALUE *argv, struct timeval *timerec)
+{
+ VALUE timeout = Qnil;
+ rb_check_arity(argc, 0, 1);
+ if (!argc || NIL_P(timeout = argv[0])) {
+ return NULL;
+ }
+ else {
+ *timerec = rb_time_interval(timeout);
+ return timerec;
+ }
+}
+
+static int
+wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv)
+{
+ int i = rb_wait_for_single_fd(fptr->fd, events, tv);
+ if (i < 0)
+ rb_sys_fail(0);
+ rb_io_check_closed(fptr);
+ return (i & events);
+}
+#endif
+
/*
* call-seq:
* io.nread -> int
*
* Returns number of bytes that can be read without blocking.
@@ -49,23 +80,25 @@
*/
static VALUE
io_nread(VALUE io)
{
- rb_io_t *fptr = NULL;
+ rb_io_t *fptr;
+ int len;
ioctl_arg n;
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
- int len = rb_io_read_pending(fptr);
+ len = rb_io_read_pending(fptr);
if (len > 0) return INT2FIX(len);
if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
if (n > 0) return ioctl_arg2num(n);
return INT2FIX(0);
}
+#ifdef HAVE_RB_IO_WAIT
static VALUE
io_wait_event(VALUE io, int event, VALUE timeout)
{
VALUE result = rb_io_wait(io, RB_INT2NUM(event), timeout);
@@ -80,10 +113,11 @@
}
else {
return Qfalse;
}
}
+#endif
/*
* call-seq:
* io.ready? -> true or false
*
@@ -92,16 +126,26 @@
static VALUE
io_ready_p(VALUE io)
{
rb_io_t *fptr;
+#ifndef HAVE_RB_IO_WAIT
+ struct timeval tv = {0, 0};
+#endif
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
if (rb_io_read_pending(fptr)) return Qtrue;
- return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0));
+#ifndef HAVE_RB_IO_WAIT
+ if (wait_for_single_fd(fptr, RB_WAITFD_IN, &tv))
+ return Qtrue;
+#else
+ if (RTEST(io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0))))
+ return Qtrue;
+#endif
+ return Qfalse;
}
/*
* call-seq:
* io.wait_readable -> true or false
@@ -113,21 +157,35 @@
*/
static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
- rb_io_t *fptr = NULL;
+ rb_io_t *fptr;
+#ifndef HAVE_RB_IO_WAIT
+ struct timeval timerec;
+ struct timeval *tv;
+#endif
- RB_IO_POINTER(io, fptr);
+ GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
+#ifndef HAVE_RB_IO_WAIT
+ tv = get_timeout(argc, argv, &timerec);
+#endif
if (rb_io_read_pending(fptr)) return Qtrue;
+#ifndef HAVE_RB_IO_WAIT
+ if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) {
+ return io;
+ }
+ return Qnil;
+#else
rb_check_arity(argc, 0, 1);
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
return io_wait_event(io, RUBY_IO_READABLE, timeout);
+#endif
}
/*
* call-seq:
* io.wait_writable -> true or false
@@ -137,21 +195,34 @@
* +false+ when times out.
*/
static VALUE
io_wait_writable(int argc, VALUE *argv, VALUE io)
{
- rb_io_t *fptr = NULL;
+ rb_io_t *fptr;
+#ifndef HAVE_RB_IO_WAIT
+ struct timeval timerec;
+ struct timeval *tv;
+#endif
- RB_IO_POINTER(io, fptr);
+ GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
+#ifndef HAVE_RB_IO_WAIT
+ tv = get_timeout(argc, argv, &timerec);
+ if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) {
+ return io;
+ }
+ return Qnil;
+#else
rb_check_arity(argc, 0, 1);
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
return io_wait_event(io, RUBY_IO_WRITABLE, timeout);
+#endif
}
+#ifdef HAVE_RB_IO_WAIT
/*
* call-seq:
* io.wait_priority -> true or false
* io.wait_priority(timeout) -> true or false
*
@@ -171,10 +242,11 @@
rb_check_arity(argc, 0, 1);
VALUE timeout = argc == 1 ? argv[0] : Qnil;
return io_wait_event(io, RUBY_IO_PRIORITY, timeout);
}
+#endif
static int
wait_mode_sym(VALUE mode)
{
if (mode == ID2SYM(rb_intern("r"))) {
@@ -226,10 +298,35 @@
*/
static VALUE
io_wait(int argc, VALUE *argv, VALUE io)
{
+#ifndef HAVE_RB_IO_WAIT
+ rb_io_t *fptr;
+ struct timeval timerec;
+ struct timeval *tv = NULL;
+ int event = 0;
+ int i;
+
+ GetOpenFile(io, fptr);
+ for (i = 0; i < argc; ++i) {
+ if (SYMBOL_P(argv[i])) {
+ event |= wait_mode_sym(argv[i]);
+ }
+ else {
+ *(tv = &timerec) = rb_time_interval(argv[i]);
+ }
+ }
+ /* rb_time_interval() and might_mode() might convert the argument */
+ rb_io_check_closed(fptr);
+ if (!event) event = RB_WAITFD_IN;
+ if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr))
+ return Qtrue;
+ if (wait_for_single_fd(fptr, event, tv))
+ return io;
+ return Qnil;
+#else
VALUE timeout = Qundef;
rb_io_event_t events = 0;
if (argc != 2 || (RB_SYMBOL_P(argv[0]) || RB_SYMBOL_P(argv[1]))) {
for (int i = 0; i < argc; i += 1) {
@@ -262,10 +359,11 @@
return Qtrue;
}
}
return io_wait_event(io, events, timeout);
+#endif
}
/*
* IO wait methods
*/
@@ -282,7 +380,9 @@
rb_define_method(rb_cIO, "wait", io_wait, -1);
rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1);
+#ifdef HAVE_RB_IO_WAIT
rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1);
+#endif
}