diff options
| author | bors <bors@rust-lang.org> | 2023-07-20 12:30:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-20 12:30:12 +0000 |
| commit | 6b53175b5d8558b69f5f46ce969fe42fb457e01b (patch) | |
| tree | 5962062e1a1d7ed5811a75fd0f234709704cfd9c /library/std/src | |
| parent | b14fd2359f47fb9a14bbfe55359db4bb3af11861 (diff) | |
| parent | fb31a1ac21833b205196128b7425f5c587cd883c (diff) | |
| download | rust-6b53175b5d8558b69f5f46ce969fe42fb457e01b.tar.gz rust-6b53175b5d8558b69f5f46ce969fe42fb457e01b.zip | |
Auto merge of #113861 - ibraheemdev:mpsc-tls-bug, r=Mark-Simulacrum
Avoid tls access while iterating through mpsc thread entries Upstream fix: https://github.com/crossbeam-rs/crossbeam/pull/802. Possibly fixes https://github.com/rust-lang/rust/issues/113726.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sync/mpmc/waker.rs | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/library/std/src/sync/mpmc/waker.rs b/library/std/src/sync/mpmc/waker.rs index 4912ca4f815..9aab1b9417e 100644 --- a/library/std/src/sync/mpmc/waker.rs +++ b/library/std/src/sync/mpmc/waker.rs @@ -66,26 +66,32 @@ impl Waker { /// Attempts to find another thread's entry, select the operation, and wake it up. #[inline] pub(crate) fn try_select(&mut self) -> Option<Entry> { - self.selectors - .iter() - .position(|selector| { - // Does the entry belong to a different thread? - selector.cx.thread_id() != current_thread_id() - && selector // Try selecting this operation. - .cx - .try_select(Selected::Operation(selector.oper)) - .is_ok() - && { - // Provide the packet. - selector.cx.store_packet(selector.packet); - // Wake the thread up. - selector.cx.unpark(); - true - } - }) - // Remove the entry from the queue to keep it clean and improve - // performance. - .map(|pos| self.selectors.remove(pos)) + if self.selectors.is_empty() { + None + } else { + let thread_id = current_thread_id(); + + self.selectors + .iter() + .position(|selector| { + // Does the entry belong to a different thread? + selector.cx.thread_id() != thread_id + && selector // Try selecting this operation. + .cx + .try_select(Selected::Operation(selector.oper)) + .is_ok() + && { + // Provide the packet. + selector.cx.store_packet(selector.packet); + // Wake the thread up. + selector.cx.unpark(); + true + } + }) + // Remove the entry from the queue to keep it clean and improve + // performance. + .map(|pos| self.selectors.remove(pos)) + } } /// Notifies all operations waiting to be ready. |
