Skip to content

Commit 3b6ae15

Browse files
committed
std: fix deadlock in Parker
1 parent fd76552 commit 3b6ae15

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

library/std/src/sys/itron/wait_flag.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ impl WaitFlag {
4242
}
4343

4444
/// Wait for the wait flag to be raised or the timeout to occur.
45-
pub fn wait_timeout(&self, dur: Duration) {
45+
///
46+
/// Returns whether the flag was raised (`true`) or the operation timed out (`false`).
47+
pub fn wait_timeout(&self, dur: Duration) -> bool {
4648
let mut token = MaybeUninit::uninit();
47-
let er = with_tmos(dur, |tmout| unsafe {
49+
let res = with_tmos(dur, |tmout| unsafe {
4850
abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout)
4951
});
50-
if er != abi::E_OK && er != abi::E_TMOUT {
51-
fail(er, &"twai_flg");
52+
53+
match res {
54+
abi::E_OK => true,
55+
abi::E_TMOUT => false,
56+
error => fail(error, &"twai_flg"),
5257
}
5358
}
5459

library/std/src/sys_common/thread_parker/wait_flag.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! Some operating systems provide low-level parking primitives like wait counts,
44
//! event flags or semaphores which are not susceptible to race conditions (meaning
5-
//! the wakeup can occure before the wait operation). To implement the `std` thread
5+
//! the wakeup can occur before the wait operation). To implement the `std` thread
66
//! parker on top of these primitives, we only have to ensure that parking is fast
77
//! when the thread token is available, the atomic ordering guarantees are maintained
88
//! and spurious wakeups are minimized.
@@ -73,10 +73,10 @@ impl Parker {
7373
_ => panic!("inconsistent park state"),
7474
}
7575

76-
self.wait_flag.wait_timeout(dur);
76+
let wakeup = self.wait_flag.wait_timeout(dur);
7777
let state = self.state.swap(EMPTY, SeqCst);
78-
if state == NOTIFIED {
79-
// The token was made available after the timeout occurred, but before
78+
if state == NOTIFIED && !wakeup {
79+
// The token was made available after the wait timed out, but before
8080
// we reset the state, so we need to reset the wait flag to avoid
8181
// spurious wakeups. This wait has no timeout, but we know it will
8282
// return quickly, as the unparking thread will definitely raise the

0 commit comments

Comments
 (0)