diff options
| author | joboet <jonasboettiger@icloud.com> | 2023-08-07 19:13:34 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2023-08-07 19:13:34 +0200 |
| commit | fd9fcc580a40bdf398576199c5e8c3ebe12de9c6 (patch) | |
| tree | c090ebc6728c17ee5fab3a85f3569cee64eada8a | |
| parent | a6236fa460811bbd4a08a94db249c344fa9f2220 (diff) | |
| download | rust-fd9fcc580a40bdf398576199c5e8c3ebe12de9c6.tar.gz rust-fd9fcc580a40bdf398576199c5e8c3ebe12de9c6.zip | |
std: synchronize with all calls to `unpark` in id-based thread parker
| -rw-r--r-- | library/std/src/sys_common/thread_parking/id.rs | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/library/std/src/sys_common/thread_parking/id.rs b/library/std/src/sys_common/thread_parking/id.rs index 15042fc3bee..04667439660 100644 --- a/library/std/src/sys_common/thread_parking/id.rs +++ b/library/std/src/sys_common/thread_parking/id.rs @@ -56,18 +56,14 @@ impl Parker { self.init_tid(); // Changes NOTIFIED to EMPTY and EMPTY to PARKED. - let mut state = self.state.fetch_sub(1, Acquire).wrapping_sub(1); - if state == PARKED { + let state = self.state.fetch_sub(1, Acquire); + if state == EMPTY { // Loop to guard against spurious wakeups. - while state == PARKED { + // The state must be reset with acquire ordering to ensure that all + // calls to `unpark` synchronize with this thread. + while self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed).is_err() { park(self.state.as_ptr().addr()); - state = self.state.load(Acquire); } - - // Since the state change has already been observed with acquire - // ordering, the state can be reset with a relaxed store instead - // of a swap. - self.state.store(EMPTY, Relaxed); } } @@ -78,8 +74,7 @@ impl Parker { if state == PARKED { park_timeout(dur, self.state.as_ptr().addr()); // Swap to ensure that we observe all state changes with acquire - // ordering, even if the state has been changed after the timeout - // occurred. + // ordering. self.state.swap(EMPTY, Acquire); } } |
