Bug #6416
closedDeadlock when calling Thread#join from signal interrupt context
Description
=begin
The interpreter can deadlock when calling Thread#join both from the main context and from the signal handler context.
t = Thread.new{ sleep 3 }
Signal.trap "SIGINT" do
t.join
end
puts 'Press ctrl + c now'
t.join
The above will deadlock on linux x86_64 with ruby 1.9.x and ruby trunk. It works fine with ruby 1.8.7-p352 and JRuby.
=end
Updated by mame (Yusuke Endoh) about 10 years ago
- Status changed from Open to Assigned
- Assignee set to kosaki (Motohiro KOSAKI)
Kosaki-san, could you take a look?
--
Yusuke Endoh mame@tsg.ne.jp
Updated by kosaki (Motohiro KOSAKI) about 10 years ago
- Assignee changed from kosaki (Motohiro KOSAKI) to ko1 (Koichi Sasada)
Hi ko1,
This is because thread_join() is not designed reentrant. It can insert a thread twice join_list. And then, join_list
is going to become circular ring and it lead to deadlock.
So, I think th.join in trap context should raise ThreadError. What do you think?
Updated by ko1 (Koichi Sasada) over 9 years ago
- Assignee changed from ko1 (Koichi Sasada) to kosaki (Motohiro KOSAKI)
I agree with kosaki-san's comment.
Updated by kosaki (Motohiro KOSAKI) over 9 years ago
- Status changed from Assigned to Closed
Fixed at r37852.
Thanks, Timothy!
Updated by authorNari (Narihiro Nakamura) over 9 years ago
Hello
I need sometimes to call Thread#join in Signal.trap when I want to implement safe termination in a server.
For instance: https://gist.github.com/4158509
Is it a wrong use case in the first place?
Thanks.
Updated by kosaki (Motohiro KOSAKI) over 9 years ago
Nari,
In your case, main thread and trap handler uses the same mutex and it is racy and deadlockable. Even if I revert my change, it wouldn't work.
Updated by authorNari (Narihiro Nakamura) over 9 years ago
kosaki (Motohiro KOSAKI) wrote:
Nari,
In your case, main thread and trap handler uses the same mutex and it is racy and deadlockable. Even if I revert my change, it wouldn't work.
I see, Thanks!