Skip to content

Commit 2eb6969

Browse files
committed
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);`
2 parents 3b50455 + b352d2d commit 2eb6969

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

Diff for: src/libstd/thread/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,10 @@ pub fn park() {
796796
let mut m = thread.inner.lock.lock().unwrap();
797797
match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
798798
Ok(_) => {}
799-
Err(NOTIFIED) => return, // notified after we locked
799+
Err(NOTIFIED) => {
800+
thread.inner.state.store(EMPTY, SeqCst);
801+
return;
802+
} // should consume this notification, so prohibit spurious wakeups in next park.
800803
Err(_) => panic!("inconsistent park state"),
801804
}
802805
loop {
@@ -882,7 +885,10 @@ pub fn park_timeout(dur: Duration) {
882885
let m = thread.inner.lock.lock().unwrap();
883886
match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
884887
Ok(_) => {}
885-
Err(NOTIFIED) => return, // notified after we locked
888+
Err(NOTIFIED) => {
889+
thread.inner.state.store(EMPTY, SeqCst);
890+
return;
891+
} // should consume this notification, so prohibit spurious wakeups in next park.
886892
Err(_) => panic!("inconsistent park_timeout state"),
887893
}
888894

0 commit comments

Comments
 (0)