1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

io.c: get rid of race condition

* io.c (rb_io_close_write): detach tied IO for writing before closing
  to get rid of race condition.  [ruby-list:49598]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43114 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-10-02 05:20:02 +00:00
parent 145ecb6872
commit f0d8be4e2b
3 changed files with 18 additions and 2 deletions

View file

@ -1,4 +1,7 @@
Wed Oct 2 14:18:56 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> Wed Oct 2 14:19:57 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (rb_io_close_write): detach tied IO for writing before closing
to get rid of race condition. [ruby-list:49598]
* io.c (rb_io_close_read): keep fptr in write_io to be discarded, to * io.c (rb_io_close_read): keep fptr in write_io to be discarded, to
fix freed pointer access when it is in use by other threads, and get fix freed pointer access when it is in use by other threads, and get

2
io.c
View file

@ -4492,12 +4492,12 @@ rb_io_close_write(VALUE io)
rb_raise(rb_eIOError, "closing non-duplex IO for writing"); rb_raise(rb_eIOError, "closing non-duplex IO for writing");
} }
rb_io_close(write_io);
if (io != write_io) { if (io != write_io) {
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
fptr->tied_io_for_writing = 0; fptr->tied_io_for_writing = 0;
fptr->mode &= ~FMODE_DUPLEX; fptr->mode &= ~FMODE_DUPLEX;
} }
rb_io_close(write_io);
return Qnil; return Qnil;
} }

View file

@ -1380,6 +1380,19 @@ class TestIO < Test::Unit::TestCase
end end
end end
def test_close_read_write_separately
bug = '[ruby-list:49598]'
(1..10).each do |i|
assert_nothing_raised(IOError, "#{bug} trying ##{i}") do
IO.popen(EnvUtil.rubybin, "r+") {|f|
th = Thread.new {f.close_write}
f.close_read
th.join
}
end
end
end
def test_pid def test_pid
r, w = IO.pipe r, w = IO.pipe
assert_equal(nil, r.pid) assert_equal(nil, r.pid)