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:
commit
2eb6969c6a
1 changed files with 8 additions and 2 deletions
|
@ -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"),
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue