From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/crossbeam-epoch/src/default.rs | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 vendor/crossbeam-epoch/src/default.rs (limited to 'vendor/crossbeam-epoch/src/default.rs') diff --git a/vendor/crossbeam-epoch/src/default.rs b/vendor/crossbeam-epoch/src/default.rs new file mode 100644 index 000000000..c2b4852a4 --- /dev/null +++ b/vendor/crossbeam-epoch/src/default.rs @@ -0,0 +1,85 @@ +//! The default garbage collector. +//! +//! For each thread, a participant is lazily initialized on its first use, when the current thread +//! is registered in the default collector. If initialized, the thread's participant will get +//! destructed on thread exit, which in turn unregisters the thread. + +use crate::collector::{Collector, LocalHandle}; +use crate::guard::Guard; +use crate::primitive::thread_local; +#[cfg(not(crossbeam_loom))] +use once_cell::sync::Lazy; + +/// The global data for the default garbage collector. +#[cfg(not(crossbeam_loom))] +static COLLECTOR: Lazy = Lazy::new(Collector::new); +// FIXME: loom does not currently provide the equivalent of Lazy: +// https://github.com/tokio-rs/loom/issues/263 +#[cfg(crossbeam_loom)] +loom::lazy_static! { + /// The global data for the default garbage collector. + static ref COLLECTOR: Collector = Collector::new(); +} + +thread_local! { + /// The per-thread participant for the default garbage collector. + static HANDLE: LocalHandle = COLLECTOR.register(); +} + +/// Pins the current thread. +#[inline] +pub fn pin() -> Guard { + with_handle(|handle| handle.pin()) +} + +/// Returns `true` if the current thread is pinned. +#[inline] +pub fn is_pinned() -> bool { + with_handle(|handle| handle.is_pinned()) +} + +/// Returns the default global collector. +pub fn default_collector() -> &'static Collector { + &COLLECTOR +} + +#[inline] +fn with_handle(mut f: F) -> R +where + F: FnMut(&LocalHandle) -> R, +{ + HANDLE + .try_with(|h| f(h)) + .unwrap_or_else(|_| f(&COLLECTOR.register())) +} + +#[cfg(all(test, not(crossbeam_loom)))] +mod tests { + use crossbeam_utils::thread; + + #[test] + fn pin_while_exiting() { + struct Foo; + + impl Drop for Foo { + fn drop(&mut self) { + // Pin after `HANDLE` has been dropped. This must not panic. + super::pin(); + } + } + + thread_local! { + static FOO: Foo = Foo; + } + + thread::scope(|scope| { + scope.spawn(|_| { + // Initialize `FOO` and then `HANDLE`. + FOO.with(|_| ()); + super::pin(); + // At thread exit, `HANDLE` gets dropped first and `FOO` second. + }); + }) + .unwrap(); + } +} -- cgit v1.2.3