about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorIbraheem Ahmed <ibraheem@ibraheem.ca>2023-07-19 11:50:29 -0400
committerIbraheem Ahmed <ibraheem@ibraheem.ca>2023-07-19 11:50:29 -0400
commitfb31a1ac21833b205196128b7425f5c587cd883c (patch)
tree538298cf1205898dcd54a084872d5bdef082869f /library/std/src
parent77e24f90f599070af2d8051ef9adad7fe528dd78 (diff)
downloadrust-fb31a1ac21833b205196128b7425f5c587cd883c.tar.gz
rust-fb31a1ac21833b205196128b7425f5c587cd883c.zip
avoid tls access while iterating through mpsc thread entries
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sync/mpmc/waker.rs46
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.