9aa6573359
tsleep() used to cancel the timer with: if(up->tt != nil) timerdel(up); which still can result in twakeup() to fire after tsleep() returns (because we set Timer.tt to nil *before* we call the tfn). in most cases, this is not an issue as the Rendez* usually is just &up->sleep, but when it is dynamically allocated or on the stack like in tsemacquire(), twakeup() will call wakeup() on a potentially garbage Rendez structure! to fix the race, we execute the wakup() with the Timer lock held, and set p->trend to nil only after we called wakeup(). that way, the timerdel(); which unconditionally locks the Timer; can act as a proper barrier and use up->trend == nil as the condition if the timer has already fired. |
||
---|---|---|
.. | ||
doc | ||
games/lib | ||
include | ||
lib | ||
man | ||
src |