From 17ed23bb6dfc942a8c51658b01135c3e2807ccf0 Mon Sep 17 00:00:00 2001 From: normal Date: Tue, 14 Aug 2018 17:07:36 +0000 Subject: [PATCH] spec/ruby/optional/capi/io_spec.rb: fix fragile spec from unpredictable errno rb_io_wait_readable and rb_io_wait_writable depend on the TSD errno value. Due to the recent changes in r64352-r64353 to restructure GVL, errno could be set to EAGAIN from the signal self-pipe and cause the rb_io_wait_readable spec to block unexpectedly. This should fix rubyspec timeouts on Solaris: http://rubyci.s3.amazonaws.com/unstable11s/ruby-trunk/log/20180814T042506Z.fail.html.gz * spec/ruby/optional/capi/ext/io_spec.c: add errno= setter method * spec/ruby/optional/capi/io_spec.rb: set errno to appropriate values for tests git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64359 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- spec/ruby/optional/capi/ext/io_spec.c | 13 +++++++++++++ spec/ruby/optional/capi/io_spec.rb | 3 +++ 2 files changed, 16 insertions(+) diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index 40069bd54b..1b47830fa4 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -218,6 +218,17 @@ VALUE io_spec_rb_io_close(VALUE self, VALUE io) { } #endif +/* + * this is needed to ensure rb_io_wait_*able functions behave + * predictably because errno may be set to unexpected values + * otherwise. + */ +static VALUE io_spec_errno_set(VALUE self, VALUE val) { + int e = NUM2INT(val); + errno = e; + return val; +} + void Init_io_spec(void) { VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject); @@ -296,6 +307,8 @@ void Init_io_spec(void) { #ifdef HAVE_RB_CLOEXEC_OPEN rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3); #endif + + rb_define_method(cls, "errno=", io_spec_errno_set, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index 466bfe5a41..a832c6a93b 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -236,6 +236,7 @@ describe "C-API IO function" do describe "rb_io_wait_writable" do it "returns false if there is no error condition" do + @o.errno = 0 @o.rb_io_wait_writable(@w_io).should be_false end @@ -254,6 +255,7 @@ describe "C-API IO function" do platform_is_not :windows do describe "rb_io_wait_readable" do it "returns false if there is no error condition" do + @o.errno = 0 @o.rb_io_wait_readable(@r_io, false).should be_false end @@ -271,6 +273,7 @@ describe "C-API IO function" do @w_io.write "rb_io_wait_readable" end + @o.errno = Errno::EAGAIN.new.errno @o.rb_io_wait_readable(@r_io, true).should be_true @o.instance_variable_get(:@read_data).should == "rb_io_wait_re"