static public Method

IO.select(...)

IO.select(read_array 
[, write_array 
[, error_array 
[, timeout]]] )   array  or  nil

See Kernel#select.

Source Code

/*
*  call-seq:
*     IO.select(read_array 
*               [, write_array 
*               [, error_array 
*               [, timeout]]] ) =>  array  or  nil
*  
*  See <code>Kernel#select</code>.
*/

static VALUE
rb_f_select(argc, argv, obj)
   int argc;
   VALUE *argv;
   VALUE obj;
{
   VALUE read, write, except, timeout, res, list;
   fd_set rset, wset, eset, pset;
   fd_set *rp, *wp, *ep;
   struct timeval *tp, timerec;
   OpenFile *fptr;
   long i;
   int max = 0, n;
   int interrupt_flag = 0;
   int pending = 0;

   rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout);
   if (NIL_P(timeout)) {
       tp = 0;
   }
   else {
       timerec = rb_time_interval(timeout);
       tp = &timerec;
   }

   FD_ZERO(&pset);
   if (!NIL_P(read)) {
       Check_Type(read, T_ARRAY);
       rp = &rset;
       FD_ZERO(rp);
       for (i=0; i<RARRAY(read)->len; i++) {
           GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
           FD_SET(fileno(fptr->f), rp);
           if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */
               pending++;
               FD_SET(fileno(fptr->f), &pset);
           }
           if (max < fileno(fptr->f)) max = fileno(fptr->f);
       }
       if (pending) {         /* no blocking if there's buffered data */
           timerec.tv_sec = timerec.tv_usec = 0;
           tp = &timerec;
       }
   }
   else
       rp = 0;

   if (!NIL_P(write)) {
       Check_Type(write, T_ARRAY);
       wp = &wset;
       FD_ZERO(wp);
       for (i=0; i<RARRAY(write)->len; i++) {
           GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
           FD_SET(fileno(fptr->f), wp);
           if (max < fileno(fptr->f)) max = fileno(fptr->f);
           if (fptr->f2) {
               FD_SET(fileno(fptr->f2), wp);
               if (max < fileno(fptr->f2)) max = fileno(fptr->f2);
           }
       }
   }
   else
       wp = 0;

   if (!NIL_P(except)) {
       Check_Type(except, T_ARRAY);
       ep = &eset;
       FD_ZERO(ep);
       for (i=0; i<RARRAY(except)->len; i++) {
           GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
           FD_SET(fileno(fptr->f), ep);
           if (max < fileno(fptr->f)) max = fileno(fptr->f);
           if (fptr->f2) {
               FD_SET(fileno(fptr->f2), ep);
               if (max < fileno(fptr->f2)) max = fileno(fptr->f2);
           }
       }
   }
   else {
       ep = 0;
   }

   max++;

   n = rb_thread_select(max, rp, wp, ep, tp);
   if (n < 0) {
       rb_sys_fail(0);
   }
   if (!pending && n == 0) return Qnil; /* returns nil on timeout */

   res = rb_ary_new2(3);
   rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0));
   rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0));
   rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0));

   if (interrupt_flag == 0) {
       if (rp) {
           list = RARRAY(res)->ptr[0];
           for (i=0; i< RARRAY(read)->len; i++) {
               GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);
               if (FD_ISSET(fileno(fptr->f), rp)
                   || FD_ISSET(fileno(fptr->f), &pset)) {
                   rb_ary_push(list, rb_ary_entry(read, i));
               }
           }
       }

       if (wp) {
           list = RARRAY(res)->ptr[1];
           for (i=0; i< RARRAY(write)->len; i++) {
               GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);
               if (FD_ISSET(fileno(fptr->f), wp)) {
                   rb_ary_push(list, rb_ary_entry(write, i));
               }
               else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), wp)) {
                   rb_ary_push(list, rb_ary_entry(write, i));
               }
           }
       }

       if (ep) {
           list = RARRAY(res)->ptr[2];
           for (i=0; i< RARRAY(except)->len; i++) {
               GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);
               if (FD_ISSET(fileno(fptr->f), ep)) {
                   rb_ary_push(list, rb_ary_entry(except, i));
               }
               else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), ep)) {
                   rb_ary_push(list, rb_ary_entry(except, i));
               }
           }
       }
   }

   return res;                 /* returns an empty array on interrupt */
}
Comments

Have your say
Please use Textile formatting (click here for a cheat sheet). Use <code/> and <pre/> for code samples.
Click here to login with OpenID to to post comments.