]> git.proxmox.com Git - rustc.git/blame - vendor/parking_lot_core/src/thread_parker/mod.rs
New upstream version 1.42.0+dfsg1
[rustc.git] / vendor / parking_lot_core / src / thread_parker / mod.rs
CommitLineData
e1599b0c
XL
1use cfg_if::cfg_if;
2use std::time::Instant;
3
4/// Trait for the platform thread parker implementation.
5///
6/// All unsafe methods are unsafe because the Unix thread parker is based on
7/// pthread mutexes and condvars. Those primitives must not be moved and used
8/// from any other memory address than the one they were located at when they
9/// were initialized. As such, it's UB to call any unsafe method on
10/// `ThreadParkerT` if the implementing instance has moved since the last
11/// call to any of the unsafe methods.
12pub trait ThreadParkerT {
13 type UnparkHandle: UnparkHandleT;
14
15 const IS_CHEAP_TO_CONSTRUCT: bool;
16
17 fn new() -> Self;
18
19 /// Prepares the parker. This should be called before adding it to the queue.
20 unsafe fn prepare_park(&self);
21
22 /// Checks if the park timed out. This should be called while holding the
23 /// queue lock after park_until has returned false.
24 unsafe fn timed_out(&self) -> bool;
25
26 /// Parks the thread until it is unparked. This should be called after it has
27 /// been added to the queue, after unlocking the queue.
28 unsafe fn park(&self);
29
30 /// Parks the thread until it is unparked or the timeout is reached. This
31 /// should be called after it has been added to the queue, after unlocking
32 /// the queue. Returns true if we were unparked and false if we timed out.
33 unsafe fn park_until(&self, timeout: Instant) -> bool;
34
35 /// Locks the parker to prevent the target thread from exiting. This is
36 /// necessary to ensure that thread-local ThreadData objects remain valid.
37 /// This should be called while holding the queue lock.
38 unsafe fn unpark_lock(&self) -> Self::UnparkHandle;
39}
40
41/// Handle for a thread that is about to be unparked. We need to mark the thread
42/// as unparked while holding the queue lock, but we delay the actual unparking
43/// until after the queue lock is released.
44pub trait UnparkHandleT {
45 /// Wakes up the parked thread. This should be called after the queue lock is
46 /// released to avoid blocking the queue for too long.
47 ///
48 /// This method is unsafe for the same reason as the unsafe methods in
49 /// `ThreadParkerT`.
50 #[inline]
51 unsafe fn unpark(self);
52}
53
54cfg_if! {
55 if #[cfg(all(has_sized_atomics, any(target_os = "linux", target_os = "android")))] {
56 #[path = "linux.rs"]
57 mod imp;
58 } else if #[cfg(unix)] {
59 #[path = "unix.rs"]
60 mod imp;
61 } else if #[cfg(windows)] {
62 #[path = "windows/mod.rs"]
63 mod imp;
64 } else if #[cfg(all(has_sized_atomics, target_os = "redox"))] {
65 #[path = "redox.rs"]
66 mod imp;
67 } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
68 #[path = "sgx.rs"]
69 mod imp;
70 } else if #[cfg(all(
71 feature = "nightly",
72 target_arch = "wasm32",
73 target_feature = "atomics"
74 ))] {
75 #[path = "wasm_atomic.rs"]
76 mod imp;
77 } else if #[cfg(target_arch = "wasm32")] {
78 #[path = "wasm.rs"]
79 mod imp;
80 } else if #[cfg(all(feature = "nightly", target_os = "cloudabi"))] {
81 #[path = "cloudabi.rs"]
82 mod imp;
83 } else {
84 #[path = "generic.rs"]
85 mod imp;
86 }
87}
88
89pub use self::imp::{thread_yield, ThreadParker, UnparkHandle};