зеркало из https://github.com/github/ruby.git
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53642 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
57752a2503
Коммит
b58fac9a97
|
@ -1,3 +1,9 @@
|
|||
Sun Jan 24 16:54:11 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* test/ruby/test_array.rb (test_keep_if): Add test for
|
||||
|
|
|
@ -117,8 +117,6 @@ io_ready_p(VALUE io)
|
|||
|
||||
/*
|
||||
* 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, VALUE io)
|
|||
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)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,18 @@ class TestIOWait < Test::Unit::TestCase
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче