From: Sylvain Joyeux Date: 2010-05-03T21:17:25+09:00 Subject: [ruby-core:29970] [Bug #3212] ConditionVariable may become inconsistent for interrupted threads Issue #3212 has been updated by Sylvain Joyeux. This is *not* about having spurious wakeups or not (I understood that my knowledge of pthreads is lower than yours, and I apologize for the noise). This is about maintaining class invariants, in this case: "threads that are listed in @waiters should be the threads waiting for the CV". A few scenarios: Scenario 1 ---------- 1) Thread 'a' gets a spurious wakeup 2) Thread 'a' gets back to wait() because it is in an until loop. @waiters contains 'a' two times. 3) Thread 'b' wakes 'a' up 4) Thread 'a' leaves the synchronization section. 'a' is still listed in @waiters (the bug I am reporting) 5) Later on, 'a' goes back to sleep (for whatever reason) 6) Thread 'b' calls CV#signal and wakes up 'a', since 'a' is still in @waiters Scenario 2 ---------- 1) Thread 'a' gets a spurious wakeup 2) Thread 'a' gets back to sleep *not using CV#wait" (using mutex#sleep or Thread.sleep, for whatever reason) 3) Thread 'b' calls CV#signal, which wakes 'a' up since 'a' is still in the @waiters list. In (3), 'a' was not waiting on the CV anymore. But 'b' called a#run anyway. Scenario 3 ---------- This is a modified version of Scenario (1) 1) Thread 'a' gets a spurious wakeup 2) Thread 'a' gets back to wait() because it is in an until loop. @waiters contains 'a' two times. 3) Thread 'b' wakes 'a' up 4) Thread 'a' leaves the synchronization section. 'a' is still listed in @waiters (the bug I am reporting) 5) Thread 'b' calls CV#signal and wakes up 'a', which does not wait for the CV anymore I.e. CV#signal in (5) does *not* wake up anybody, which most likely will lead to a deadlock ---------------------------------------- http://redmine.ruby-lang.org/issues/show/3212 ---------------------------------------- http://redmine.ruby-lang.org