std: allow after-main use of synchronization primitives
By creating an unnamed thread handle when the actual one has already been destroyed, synchronization primitives using thread parking can be used even outside the Rust runtime. This also fixes an inefficiency in the queue-based `RwLock`: if `thread::current` was not initialized yet, it will create a new handle on every parking attempt without initializing `thread::current`. The private `current_or_unnamed` function introduced here fixes this.
This commit is contained in:
parent
c602e9aeaa
commit
5a856b82f3
10 changed files with 59 additions and 26 deletions
|
@ -186,7 +186,7 @@ mod current;
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use current::current;
|
||||
pub(crate) use current::{current_id, drop_current, set_current, try_current};
|
||||
pub(crate) use current::{current_id, current_or_unnamed, drop_current, set_current, try_current};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-local storage
|
||||
|
@ -1126,9 +1126,9 @@ pub fn park_timeout_ms(ms: u32) {
|
|||
#[stable(feature = "park_timeout", since = "1.4.0")]
|
||||
pub fn park_timeout(dur: Duration) {
|
||||
let guard = PanicGuard;
|
||||
// SAFETY: park_timeout is called on the parker owned by this thread.
|
||||
// SAFETY: park_timeout is called on a handle owned by this thread.
|
||||
unsafe {
|
||||
current().0.parker().park_timeout(dur);
|
||||
current().park_timeout(dur);
|
||||
}
|
||||
// No panic occurred, do not abort.
|
||||
forget(guard);
|
||||
|
@ -1426,6 +1426,15 @@ impl Thread {
|
|||
unsafe { self.0.parker().park() }
|
||||
}
|
||||
|
||||
/// Like the public [`park_timeout`], but callable on any handle. This is
|
||||
/// used to allow parking in TLS destructors.
|
||||
///
|
||||
/// # Safety
|
||||
/// May only be called from the thread to which this handle belongs.
|
||||
pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
|
||||
unsafe { self.0.parker().park_timeout(dur) }
|
||||
}
|
||||
|
||||
/// Atomically makes the handle's token available if it is not already.
|
||||
///
|
||||
/// Every thread is equipped with some basic low-level blocking support, via
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue