Project

General

Profile

Bug #10443

Updated by nobu (Nobuyoshi Nakada) over 9 years ago

If a Ruby thread calls `Process.fork` Process.fork while holding a Mutex (for example, within a `Mutex#synchronize` Mutex#synchronize block) that is also concurrently being contended for by a background thread, the thread in the child process will occasionally be unable to unlock the mutex it was holding at the time of the fork, and will hang under `rb_mutex_unlock_th` rb_mutex_unlock_th when attempting to acquire `mutex->lock`. mutex->lock. 

 I've been able to reproduce this on Ruby 2.1.1 - 2.1.3 and 2.2.0-preview1 (haven't tried elsewhere yet). 

 The attached test case demonstrates the issue, although it can take up to 20 minutes to hit a reproducing case. The test case will print one '.' each time it forks. Once it stops printing dots, it has hit this bug (the parent process is stuck in a call to `Process.wait`, Process.wait, and the child is stuck in `rb_mutex_unlock_th`). rb_mutex_unlock_th). 

 The test case consists of a global lock that is contended for by 10 background threads, in addition to the main thread, which acquires it, forks, and then releases it. 

Back