try_drop/handlers/primary/
thread_local.rs1use super::{Abstracter, DefaultOnUninit};
4use crate::handlers::common::handler::CommonHandler;
5use crate::handlers::common::thread_local::{
6 scope_guard::ScopeGuard as GenericScopeGuard, ThreadLocal as GenericThreadLocal,
7 ThreadLocalDefinition,
8};
9use crate::handlers::common::Primary;
10use crate::handlers::common::ThreadLocal as ThreadLocalScope;
11use crate::handlers::on_uninit::{ErrorOnUninit, FlagOnUninit, PanicOnUninit};
12use crate::handlers::uninit_error::UninitializedError;
13use crate::FallibleTryDropStrategy;
14use std::boxed::Box;
15use std::cell::{Cell, RefCell};
16
17use std::thread::LocalKey;
18use std::{convert, thread_local};
19
20#[cfg(feature = "ds-write")]
21use crate::handlers::common::thread_local::DefaultThreadLocalDefinition;
22
23#[cfg(feature = "ds-write")]
24use crate::handlers::on_uninit::UseDefaultOnUninit;
25
26pub type ThreadLocalPrimaryHandler<OU = DefaultOnUninit> =
28 CommonHandler<OU, ThreadLocalScope, Primary>;
29
30pub static DEFAULT_THREAD_LOCAL_PRIMARY_HANDLER: ThreadLocalPrimaryHandler =
32 ThreadLocalPrimaryHandler::DEFAULT;
33
34impl_fallible_try_drop_strategy_for!(ThreadLocalPrimaryHandler
35where
36 Scope: ThreadLocalScope,
37 Definition: ThreadLocalDefinition
38);
39
40thread_local! {
41 static PRIMARY_HANDLER: RefCell<Option<Box<dyn ThreadLocalFallibleTryDropStrategy>>> = RefCell::new(None);
42 static LOCKED: Cell<bool> = Cell::new(false);
43}
44
45impl ThreadLocalDefinition for Primary {
46 const UNINITIALIZED_ERROR: &'static str =
47 "the thread local primary handler is not initialized yet";
48 const DYN: &'static str = "ThreadLocalFallibleTryDropStrategy";
49 type ThreadLocal = Box<dyn ThreadLocalFallibleTryDropStrategy>;
50
51 fn thread_local() -> &'static LocalKey<RefCell<Option<Self::ThreadLocal>>> {
52 &PRIMARY_HANDLER
53 }
54
55 fn locked() -> &'static LocalKey<Cell<bool>> {
56 &LOCKED
57 }
58}
59
60#[cfg(feature = "ds-write")]
61impl DefaultThreadLocalDefinition for Primary {
62 fn default() -> Self::ThreadLocal {
63 let mut strategy = crate::drop_strategies::WriteDropStrategy::stderr();
64 strategy.prelude("error: ");
65 Box::new(strategy)
66 }
67}
68
69impl<T: ThreadLocalFallibleTryDropStrategy> From<T>
70 for Box<dyn ThreadLocalFallibleTryDropStrategy>
71{
72 fn from(strategy: T) -> Self {
73 Box::new(strategy)
74 }
75}
76
77type ThreadLocal = GenericThreadLocal<Primary>;
78
79pub type ScopeGuard = GenericScopeGuard<Primary>;
82
83pub type BoxDynFallibleTryDropStrategy = Box<dyn ThreadLocalFallibleTryDropStrategy>;
85
86thread_local_methods! {
87 ThreadLocal = ThreadLocal;
88 ScopeGuard = ScopeGuard;
89 GenericStrategy = ThreadLocalFallibleTryDropStrategy;
90 DynStrategy = BoxDynFallibleTryDropStrategy;
91 feature = "ds-write";
92
93 install;
95
96 install_dyn;
98
99 read;
104
105 try_read;
111
112 read_or_default;
117
118 write;
123
124 try_write;
129
130 write_or_default;
135
136 uninstall;
138
139 take;
141
142 replace;
145
146 replace_dyn;
149
150 scope;
153
154 scope_dyn;
157}