summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_thread.rb38
-rw-r--r--thread.c8
2 files changed, 45 insertions, 1 deletions
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 386a5cb89b..5f64a08155 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -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
diff --git a/thread.c b/thread.c
index baa50ea388..cc62ea3905 100644
--- a/thread.c
+++ b/thread.c
@@ -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();