[前][次][番号順一覧][スレッド一覧]

ruby-changes:21207

From: kosaki <ko1@a...>
Date: Mon, 12 Sep 2011 20:36:20 +0900 (JST)
Subject: [ruby-changes:21207] kosaki:r33256 (trunk): * thread.c (rb_thread_select): fix to ignore an argument

kosaki	2011-09-12 20:36:06 +0900 (Mon, 12 Sep 2011)

  New Revision: 33256

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33256

  Log:
    * thread.c (rb_thread_select): fix to ignore an argument
      modification of rb_thread_fd_select().
      based on a patch by Eric Wong. [Bug #5306] [ruby-core:39435]
    * thread.c (rb_fd_rcopy): New. for reverse fd copy.
    
    * test/-ext-/old_thread_select/test_old_thread_select.rb
    (test_old_select_false_positive): test for bug5306.
    
    * ext/-test-/old_thread_select/old_thread_select.c (fdset2array):
      New. convert fdsets to array.
    * ext/-test-/old_thread_select/old_thread_select.c (old_thread_select):
      return 'read', 'write', 'except' argument of rb_thread_select()
      to ruby script.

  Modified files:
    trunk/ChangeLog
    trunk/ext/-test-/old_thread_select/old_thread_select.c
    trunk/test/-ext-/old_thread_select/test_old_thread_select.rb
    trunk/thread.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33255)
+++ ChangeLog	(revision 33256)
@@ -1,3 +1,19 @@
+Mon Sep 12 19:55:00 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* thread.c (rb_thread_select): fix to ignore an argument
+	  modification of rb_thread_fd_select().
+	  based on a patch by Eric Wong. [Bug #5306] [ruby-core:39435]
+	* thread.c (rb_fd_rcopy): New. for reverse fd copy.
+
+	* test/-ext-/old_thread_select/test_old_thread_select.rb
+	(test_old_select_false_positive): test for bug5306.
+
+	* ext/-test-/old_thread_select/old_thread_select.c (fdset2array):
+	  New. convert fdsets to array.
+	* ext/-test-/old_thread_select/old_thread_select.c (old_thread_select):
+	  return 'read', 'write', 'except' argument of rb_thread_select()
+	  to ruby script.
+
 Mon Sep 12 13:38:12 2011  Nobuyoshi Nakada  <nobu@r...>
 
 	* README.EXT, README.EXT.ja (2.2.2), parse.y (rb_check_id): add
Index: thread.c
===================================================================
--- thread.c	(revision 33255)
+++ thread.c	(revision 33256)
@@ -2395,6 +2395,17 @@
     memcpy(dst->fdset, src, size);
 }
 
+static void
+rb_fd_rcopy(fd_set *dst, rb_fdset_t *src)
+{
+    size_t size = howmany(rb_fd_max(src), NFDBITS) * sizeof(fd_mask);
+
+    if (size > sizeof(fd_set)) {
+	rb_raise(rb_eArgError, "too large fdsets");
+    }
+    memcpy(dst, rb_fd_ptr(src), sizeof(fd_set));
+}
+
 void
 rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
 {
@@ -2453,6 +2464,19 @@
     rb_fd_dup(dst, src);
 }
 
+static void
+rb_fd_rcopy(fd_set *dst, rb_fdset_t *src)
+{
+    int max = rb_fd_max(src);
+
+    if (max > FD_SETSIZE) {
+	rb_raise(rb_eArgError, "too large fdsets");
+    }
+
+    memcpy(dst->fd_array, src->fdset->fd_array, max);
+    dst->fd_count = max;
+}
+
 void
 rb_fd_term(rb_fdset_t *set)
 {
@@ -2489,6 +2513,8 @@
 #define FD_CLR(i, f)	rb_fd_clr((i), (f))
 #define FD_ISSET(i, f)	rb_fd_isset((i), (f))
 
+#else
+#define rb_fd_rcopy(d, s) (*(d) = *(s))
 #endif
 
 #if defined(__CYGWIN__)
@@ -2710,12 +2736,18 @@
 
     retval = rb_thread_fd_select(max, rfds, wfds, efds, timeout);
 
-    if (rfds)
+    if (rfds) {
+	rb_fd_rcopy(read, rfds);
 	rb_fd_term(rfds);
-    if (wfds)
+    }
+    if (wfds) {
+	rb_fd_rcopy(write, wfds);
 	rb_fd_term(wfds);
-    if (efds)
+    }
+    if (efds) {
+	rb_fd_rcopy(except, efds);
 	rb_fd_term(efds);
+    }
 
     return retval;
 }
Index: ext/-test-/old_thread_select/old_thread_select.c
===================================================================
--- ext/-test-/old_thread_select/old_thread_select.c	(revision 33255)
+++ ext/-test-/old_thread_select/old_thread_select.c	(revision 33256)
@@ -25,6 +25,18 @@
     return fds;
 }
 
+static void fdset2array(VALUE dst, fd_set *fds, int max)
+{
+    int i;
+
+    rb_ary_clear(dst);
+
+    for (i = 0; i < max; i++) {
+	if (FD_ISSET(i, fds))
+	    rb_ary_push(dst, INT2NUM(i));
+    }
+}
+
 static VALUE
 old_thread_select(VALUE klass, VALUE r, VALUE w, VALUE e, VALUE timeout)
 {
@@ -45,6 +57,13 @@
     rc = rb_thread_select(max, rp, wp, ep, tvp);
     if (rc == -1)
 	rb_sys_fail("rb_wait_for_single_fd");
+
+    if (rp)
+	fdset2array(r, &rfds, max);
+    if (wp)
+	fdset2array(w, &wfds, max);
+    if (ep)
+	fdset2array(e, &efds, max);
     return INT2NUM(rc);
 }
 
Index: test/-ext-/old_thread_select/test_old_thread_select.rb
===================================================================
--- test/-ext-/old_thread_select/test_old_thread_select.rb	(revision 33255)
+++ test/-ext-/old_thread_select/test_old_thread_select.rb	(revision 33256)
@@ -34,6 +34,20 @@
     end
   end
 
+  def test_old_select_false_positive
+    bug5306 = '[ruby-core:39435]'
+    with_pipe do |r2, w2|
+      with_pipe do |r, w|
+        t0 = Time.now
+        w.syswrite '.'
+        rfds = [ r.fileno, r2.fileno ]
+        rc = IO.old_thread_select(rfds, nil, nil, nil)
+        assert_equal [ r.fileno ], rfds, bug5306
+        assert_equal 1, rc, bug5306
+      end
+    end
+  end
+
   def test_old_select_read_write_check
     with_pipe do |r, w|
       w.syswrite('.')

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]