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