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

ruby-changes:41568

From: nobu <ko1@a...>
Date: Sun, 24 Jan 2016 16:54:17 +0900 (JST)
Subject: [ruby-changes:41568] nobu:r53642 (trunk): wait readable/writable

nobu	2016-01-24 16:55:05 +0900 (Sun, 24 Jan 2016)

  New Revision: 53642

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53642

  Log:
    wait readable/writable
    
    * ext/io/wait/wait.c (io_wait_readwrite): [EXPERIMENTAL] allow to
      wait for multiple modes, readable and writable, at once.  the
      arguments may change in the future.  [Feature #12013]

  Modified files:
    trunk/ChangeLog
    trunk/ext/io/wait/wait.c
    trunk/test/io/wait/test_io_wait.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53641)
+++ ChangeLog	(revision 53642)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Jan 24 16:54:11 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/io/wait/wait.c (io_wait_readwrite): [EXPERIMENTAL] allow to
+	  wait for multiple modes, readable and writable, at once.  the
+	  arguments may change in the future.  [Feature #12013]
+
 Sat Jan 23 22:30:59 2016  K0mA  <mctj1218@g...>
 
 	* test/ruby/test_array.rb (test_keep_if): Add test for
Index: ext/io/wait/wait.c
===================================================================
--- ext/io/wait/wait.c	(revision 53641)
+++ ext/io/wait/wait.c	(revision 53642)
@@ -117,8 +117,6 @@ io_ready_p(VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/wait/wait.c#L117
 
 /*
  * call-seq:
- *   io.wait          -> IO, true or nil
- *   io.wait(timeout) -> IO, true or nil
  *   io.wait_readable          -> IO, true or nil
  *   io.wait_readable(timeout) -> IO, true or nil
  *
@@ -168,6 +166,79 @@ io_wait_writable(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/io/wait/wait.c#L166
     return Qnil;
 }
 
+static int
+wait_mode_sym(VALUE mode)
+{
+    if (mode == ID2SYM(rb_intern("r"))) {
+	return RB_WAITFD_IN;
+    }
+    if (mode == ID2SYM(rb_intern("read"))) {
+	return RB_WAITFD_IN;
+    }
+    if (mode == ID2SYM(rb_intern("readable"))) {
+	return RB_WAITFD_IN;
+    }
+    if (mode == ID2SYM(rb_intern("w"))) {
+	return RB_WAITFD_OUT;
+    }
+    if (mode == ID2SYM(rb_intern("write"))) {
+	return RB_WAITFD_OUT;
+    }
+    if (mode == ID2SYM(rb_intern("writable"))) {
+	return RB_WAITFD_OUT;
+    }
+    if (mode == ID2SYM(rb_intern("rw"))) {
+	return RB_WAITFD_IN|RB_WAITFD_OUT;
+    }
+    if (mode == ID2SYM(rb_intern("read_write"))) {
+	return RB_WAITFD_IN|RB_WAITFD_OUT;
+    }
+    if (mode == ID2SYM(rb_intern("readable_writable"))) {
+	return RB_WAITFD_IN|RB_WAITFD_OUT;
+    }
+    rb_raise(rb_eArgError, "unsupported mode: %"PRIsVALUE, mode);
+    return 0;
+}
+
+/*
+ * call-seq:
+ *   io.wait(timeout = nil, mode = :read) -> IO, true or nil
+ *
+ * Waits until IO is readable or writable without blocking and returns
+ * +self+, or +nil+ when times out.
+ * Returns +true+ immediately when buffered data is available.
+ * Optional parameter +mode+ is one of +:read+, +:write+, or
+ * +:read_write+.
+ */
+
+static VALUE
+io_wait_readwrite(int argc, VALUE *argv, VALUE io)
+{
+    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;
+}
+
 /*
  * IO wait methods
  */
@@ -177,7 +248,7 @@ Init_wait(void) https://github.com/ruby/ruby/blob/trunk/ext/io/wait/wait.c#L248
 {
     rb_define_method(rb_cIO, "nread", io_nread, 0);
     rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
-    rb_define_method(rb_cIO, "wait", io_wait_readable, -1);
+    rb_define_method(rb_cIO, "wait", io_wait_readwrite, -1);
     rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
     rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1);
 }
Index: test/io/wait/test_io_wait.rb
===================================================================
--- test/io/wait/test_io_wait.rb	(revision 53641)
+++ test/io/wait/test_io_wait.rb	(revision 53642)
@@ -134,6 +134,18 @@ class TestIOWait < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/io/wait/test_io_wait.rb#L134
     assert_raise(IOError) { @w.wait_writable }
   end
 
+  def test_wait_readwrite
+    assert_equal @r.wait(0, :write), @r.wait(0, :read_write)
+  end
+
+  def test_wait_readwrite_timeout
+    assert_equal @w, @w.wait(0.01, :read_write)
+    written = fill_pipe
+    assert_nil @w.wait(0.01, :read_write)
+    @r.read(written)
+    assert_equal @w, @w.wait(0.01, :read_write)
+  end
+
 private
 
   def fill_pipe

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

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