Bug #1525: Deadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork?
http://redmine.ruby-lang.org/issues/show/1525

Author: Hongli Lai
Status: Open, Priority: Normal
ruby -v: ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-darwin9.6.0]

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.


----------------------------------------
http://redmine.ruby-lang.org