try_drop/handlers/primary/
shim.rs1#[cfg(feature = "ds-write")]
4mod imp {
5 use super::ShimPrimaryHandler;
6 use crate::drop_strategies::WriteDropStrategy;
7 use crate::handlers::common::handler::CommonHandler;
8 use crate::handlers::common::shim::UseDefaultOnUninitShim;
9 use crate::handlers::common::Primary;
10
11 use crate::FallibleTryDropStrategy;
12 use once_cell::sync::Lazy;
13 use std::io;
14
15 pub type DefaultOnUninit = UseDefaultOnUninitShim<Primary>;
18
19 impl ShimPrimaryHandler<DefaultOnUninit> {
20 pub const DEFAULT: Self = Self::USE_DEFAULT_ON_UNINIT;
22 }
23
24 impl ShimPrimaryHandler<UseDefaultOnUninitShim<Primary>> {
25 #[allow(clippy::declare_interior_mutable_const)]
27 pub const USE_DEFAULT_ON_UNINIT: Self = Self {
28 global: CommonHandler::FLAG_ON_UNINIT,
29 thread_local: CommonHandler::FLAG_ON_UNINIT,
30 extra_data: Lazy::new(|| {
31 let mut strategy = WriteDropStrategy::stderr();
32 strategy.prelude("error: ");
33 strategy
34 }),
35 };
36
37 pub const fn use_default_on_uninit() -> Self {
40 Self::USE_DEFAULT_ON_UNINIT
41 }
42
43 fn cache(&self) -> &WriteDropStrategy<io::Stderr> {
44 &self.extra_data
45 }
46 }
47
48 impl FallibleTryDropStrategy for ShimPrimaryHandler<UseDefaultOnUninitShim<Primary>> {
49 type Error = anyhow::Error;
50
51 fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
52 self.on_all_uninit(error, |_, error| {
53 self.cache()
54 .try_handle_error(error.into())
55 .map_err(Into::into)
56 })
57 }
58 }
59}
60
61#[cfg(not(feature = "ds-write"))]
62mod imp {
63 use super::ShimPrimaryHandler;
64 use crate::handlers::on_uninit::PanicOnUninit;
65
66 pub type DefaultOnUninit = PanicOnUninit;
69
70 impl ShimPrimaryHandler<DefaultOnUninit> {
71 pub const DEFAULT: Self = Self::PANIC_ON_UNINIT;
72 }
73}
74
75use crate::adapters::ArcError;
76use crate::handlers::common::handler::CommonShimHandler;
77use crate::handlers::common::shim::OnUninitShim;
78use crate::handlers::common::Primary;
79use crate::handlers::on_uninit::{DoNothingOnUninit, ErrorOnUninit, FlagOnUninit, PanicOnUninit};
80use crate::FallibleTryDropStrategy;
81pub use imp::DefaultOnUninit;
82
83pub type ShimPrimaryHandler<OU = DefaultOnUninit> = CommonShimHandler<OU, Primary>;
86
87pub static DEFAULT_SHIM_PRIMARY_HANDLER: ShimPrimaryHandler = ShimPrimaryHandler::DEFAULT;
89
90impl<OU: OnUninitShim> ShimPrimaryHandler<OU> {
91 fn on_all_uninit(
92 &self,
93 error: anyhow::Error,
94 f: impl FnOnce(anyhow::Error, ArcError) -> anyhow::Result<()>,
95 ) -> anyhow::Result<()> {
96 let error = ArcError::new(error);
97
98 match self
99 .thread_local
100 .try_handle_error(ArcError::clone(&error).into())
101 {
102 Ok(()) => Ok(()),
103 Err(_) if self.thread_local.last_drop_failed() => {
104 match self.global.try_handle_error(ArcError::clone(&error).into()) {
105 Ok(()) => Ok(()),
106 Err(uninit_error) if self.global.last_drop_failed() => f(uninit_error, error),
107 Err(error) => Err(error),
108 }
109 }
110 Err(error) => Err(error),
111 }
112 }
113}
114
115impl FallibleTryDropStrategy for ShimPrimaryHandler<ErrorOnUninit> {
116 type Error = anyhow::Error;
117
118 fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
119 self.on_all_uninit(error, |uninit_error, _| Err(uninit_error))
120 }
121}
122
123impl FallibleTryDropStrategy for ShimPrimaryHandler<PanicOnUninit> {
124 type Error = anyhow::Error;
125
126 fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
127 self.on_all_uninit(
128 error,
129 |_, error| panic!("neither the thread local nor the global primary handlers are initialized (but here's the drop error anyway: {error})")
130 )
131 }
132}
133
134impl FallibleTryDropStrategy for ShimPrimaryHandler<DoNothingOnUninit> {
135 type Error = anyhow::Error;
136
137 fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
138 self.on_all_uninit(error, |_, _| Ok(()))
139 }
140}
141
142impl FallibleTryDropStrategy for ShimPrimaryHandler<FlagOnUninit> {
143 type Error = anyhow::Error;
144
145 fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
146 let mut last_drop_failed = false;
147 let result = self.on_all_uninit(error, |uninit_error, _| {
148 last_drop_failed = true;
149 Err(uninit_error)
150 });
151
152 self.set_last_drop_failed(last_drop_failed);
153
154 result
155 }
156}