Bug #1525
closedDeadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork?
Description
=begin
The following code seems to cause a VM-wide deadlock on 1.9:
require 'thread'
lock = Mutex.new
cond = ConditionVariable.new
t = Thread.new do
lock.synchronize do
cond.wait(lock)
end
end
pid = fork do
# Child
STDOUT.write "This is the child process.\n"
STDOUT.write "Child process exiting.\n"
end
STDOUT.write("Child PID = #{pid}\n")
Process.waitpid(pid)
The expected output is:
Child PID = xxxx
This is the child process.
Child process exiting.
After the exit message, Ruby should exit.
Instead, Ruby 1.9 gives:
Child PID = 15493
This is the child process.
(process hangs here)
Ruby 1.8 does not suffer from this problem.
Upon debugging Ruby, I've found that Ruby is stuck in blocking_region_end(), at the following line:
native_mutex_lock(&th->vm->global_vm_lock);
blocking_region_end() was called as part of rb_write_internal(), right after writing "This is the child process\n" to stdout. This problem only occurs if there's a background thread that's waiting on a ConditionVariable. If you remove the thread then the deadlock does not occur.
=end
Files