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

thread.c: fix deadlock

* thread.c (thread_join_sleep): the target thread may exit during
  `RUBY_VM_CHECK_INTS_BLOCKING`, but `sleep_forever` does not
  consider the condition change to wait.
  [ruby-core:84248] [Bug #14181]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61274 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-12-15 07:27:04 +00:00
parent 57b0489cdb
commit f5183827dc
2 changed files with 45 additions and 1 deletions

View file

@ -1249,4 +1249,42 @@ q.pop
end
_end
end
def test_signal_at_join
if /mswin|mingw/ =~ RUBY_PLATFORM
skip "can't trap a signal from another process on Windows"
# opt = {new_pgroup: true}
end
assert_separately([], "#{<<~"{#"}\n#{<<~'};'}")
{#
n = 1000
sig = :INT
trap(sig) {}
IO.popen([EnvUtil.rubybin, "-e", "#{<<~"{#1"}\n#{<<~'};#1'}"], "r+") do |f|
tpid = #{$$}
sig = :#{sig}
{#1
STDOUT.sync = true
while gets
puts
Process.kill(sig, tpid)
end
};#1
assert_nothing_raised do
n.times do
w = Thread.start do
sleep 30
end
begin
f.puts
f.gets
ensure
w.kill
w.join
end
end
end
end
};
end
end

View file

@ -883,7 +883,13 @@ thread_join_sleep(VALUE arg)
while (target_th->status != THREAD_KILLED) {
if (forever) {
sleep_forever(th, TRUE, FALSE);
th->status = THREAD_STOPPED_FOREVER;
th->vm->sleeper++;
rb_check_deadlock(th->vm);
native_sleep(th, 0);
th->vm->sleeper--;
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
th->status = THREAD_RUNNABLE;
}
else {
double now = timeofday();