1 //! The default garbage collector.
2 //!
3 //! For each thread, a participant is lazily initialized on its first use, when the current thread
4 //! is registered in the default collector. If initialized, the thread's participant will get
5 //! destructed on thread exit, which in turn unregisters the thread.
6
7 use crate::collector::{Collector, LocalHandle};
8 use crate::guard::Guard;
9 use crate::primitive::{lazy_static, thread_local};
10
11 lazy_static! {
12 /// The global data for the default garbage collector.
13 static ref COLLECTOR: Collector = Collector::new();
14 }
15
16 thread_local! {
17 /// The per-thread participant for the default garbage collector.
18 static HANDLE: LocalHandle = COLLECTOR.register();
19 }
20
21 /// Pins the current thread.
22 #[inline]
pin() -> Guard23 pub fn pin() -> Guard {
24 with_handle(|handle| handle.pin())
25 }
26
27 /// Returns `true` if the current thread is pinned.
28 #[inline]
is_pinned() -> bool29 pub fn is_pinned() -> bool {
30 with_handle(|handle| handle.is_pinned())
31 }
32
33 /// Returns the default global collector.
default_collector() -> &'static Collector34 pub fn default_collector() -> &'static Collector {
35 &COLLECTOR
36 }
37
38 #[inline]
with_handle<F, R>(mut f: F) -> R where F: FnMut(&LocalHandle) -> R,39 fn with_handle<F, R>(mut f: F) -> R
40 where
41 F: FnMut(&LocalHandle) -> R,
42 {
43 HANDLE
44 .try_with(|h| f(h))
45 .unwrap_or_else(|_| f(&COLLECTOR.register()))
46 }
47
48 #[cfg(all(test, not(crossbeam_loom)))]
49 mod tests {
50 use crossbeam_utils::thread;
51
52 #[test]
pin_while_exiting()53 fn pin_while_exiting() {
54 struct Foo;
55
56 impl Drop for Foo {
57 fn drop(&mut self) {
58 // Pin after `HANDLE` has been dropped. This must not panic.
59 super::pin();
60 }
61 }
62
63 thread_local! {
64 static FOO: Foo = Foo;
65 }
66
67 thread::scope(|scope| {
68 scope.spawn(|_| {
69 // Initialize `FOO` and then `HANDLE`.
70 FOO.with(|_| ());
71 super::pin();
72 // At thread exit, `HANDLE` gets dropped first and `FOO` second.
73 });
74 })
75 .unwrap();
76 }
77 }
78