1
Fork 0

Auto merge of #51290 - Pslydhh:master, r=alexcrichton

park/park_timeout: prohibit spurious wakeups in next park

<pre><code>
// The implementation currently uses the trivial strategy of a Mutex+Condvar
// with wakeup flag, which does not actually allow spurious wakeups.
</pre></code>

Because does not actually allow spurious wakeups.
so we have let thread.inner.cvar.wait(m) in the loop to prohibit spurious wakeups.
but if notified after we locked, this notification doesn't be consumed, it return, the next park will consume this notification...this is also 'spurious wakeup' case, 'one unpark() wakeups two  park()'.

We should improve this situation:
`thread.inner.state.store(EMPTY, SeqCst);`
This commit is contained in:
bors 2018-06-29 07:34:13 +00:00
commit 2eb6969c6a

View file

@ -796,7 +796,10 @@ pub fn park() {
let mut m = thread.inner.lock.lock().unwrap();
match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
Ok(_) => {}
Err(NOTIFIED) => return, // notified after we locked
Err(NOTIFIED) => {
thread.inner.state.store(EMPTY, SeqCst);
return;
} // should consume this notification, so prohibit spurious wakeups in next park.
Err(_) => panic!("inconsistent park state"),
}
loop {
@ -882,7 +885,10 @@ pub fn park_timeout(dur: Duration) {
let m = thread.inner.lock.lock().unwrap();
match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
Ok(_) => {}
Err(NOTIFIED) => return, // notified after we locked
Err(NOTIFIED) => {
thread.inner.state.store(EMPTY, SeqCst);
return;
} // should consume this notification, so prohibit spurious wakeups in next park.
Err(_) => panic!("inconsistent park_timeout state"),
}