Ruby 1.9.3p327(2012-11-10revision37606)
ext/-test-/old_thread_select/old_thread_select.c
Go to the documentation of this file.
00001 /* test case for deprecated C API */
00002 #include "ruby/ruby.h"
00003 #include "ruby/io.h"
00004 
00005 static fd_set * array2fdset(fd_set *fds, VALUE ary, int *max)
00006 {
00007     long i;
00008 
00009     if (NIL_P(ary))
00010         return NULL;
00011 
00012     FD_ZERO(fds);
00013     Check_Type(ary, T_ARRAY);
00014     for (i = 0; i < RARRAY_LEN(ary); i++) {
00015         VALUE val = RARRAY_PTR(ary)[i];
00016         int fd;
00017 
00018         Check_Type(val, T_FIXNUM);
00019         fd = FIX2INT(val);
00020         if (fd >= *max)
00021             *max = fd + 1;
00022         FD_SET(fd, fds);
00023     }
00024 
00025     return fds;
00026 }
00027 
00028 static void fdset2array(VALUE dst, fd_set *fds, int max)
00029 {
00030     int i;
00031 
00032     rb_ary_clear(dst);
00033 
00034     for (i = 0; i < max; i++) {
00035         if (FD_ISSET(i, fds))
00036             rb_ary_push(dst, INT2NUM(i));
00037     }
00038 }
00039 
00040 static VALUE
00041 old_thread_select(VALUE klass, VALUE r, VALUE w, VALUE e, VALUE timeout)
00042 {
00043     struct timeval tv;
00044     struct timeval *tvp = NULL;
00045     fd_set rfds, wfds, efds;
00046     fd_set *rp, *wp, *ep;
00047     int rc;
00048     int max = 0;
00049 
00050     if (!NIL_P(timeout)) {
00051         tv = rb_time_timeval(timeout);
00052         tvp = &tv;
00053     }
00054     rp = array2fdset(&rfds, r, &max);
00055     wp = array2fdset(&wfds, w, &max);
00056     ep = array2fdset(&efds, e, &max);
00057     rc = rb_thread_select(max, rp, wp, ep, tvp);
00058     if (rc == -1)
00059         rb_sys_fail("rb_wait_for_single_fd");
00060 
00061     if (rp)
00062         fdset2array(r, &rfds, max);
00063     if (wp)
00064         fdset2array(w, &wfds, max);
00065     if (ep)
00066         fdset2array(e, &efds, max);
00067     return INT2NUM(rc);
00068 }
00069 
00070 void
00071 Init_old_thread_select(void)
00072 {
00073     rb_define_singleton_method(rb_cIO, "old_thread_select",
00074                                old_thread_select, 4);
00075 }
00076