|
1 | 1 | use std::env; |
2 | 2 | use std::ffi::OsString; |
3 | 3 | use std::fmt::Debug; |
4 | | -use std::future::Future; |
5 | 4 | use std::io; |
6 | | -use std::panic; |
| 5 | +use std::io::IsTerminal; |
7 | 6 | use std::path::PathBuf; |
8 | | -use std::sync::Once; |
9 | | -use std::{cell::RefCell, io::IsTerminal}; |
10 | 7 | #[cfg(feature = "test")] |
11 | 8 | use std::{ |
12 | 9 | collections::HashMap, |
@@ -142,92 +139,6 @@ impl home::env::Env for Process { |
142 | 139 | } |
143 | 140 | } |
144 | 141 |
|
145 | | -static HOOK_INSTALLED: Once = Once::new(); |
146 | | - |
147 | | -fn ensure_hook() { |
148 | | - HOOK_INSTALLED.call_once(|| { |
149 | | - let orig_hook = panic::take_hook(); |
150 | | - panic::set_hook(Box::new(move |info| { |
151 | | - clear_process(); |
152 | | - orig_hook(info); |
153 | | - })); |
154 | | - }); |
155 | | -} |
156 | | - |
157 | | -/// Run a function in the context of a process definition and a tokio runtime. |
158 | | -/// |
159 | | -/// The process state is injected into a thread-local in every work thread of |
160 | | -/// the runtime, but this requires access to the runtime builder, so this |
161 | | -/// function must be the one to create the runtime. |
162 | | -pub fn with_runtime<'a, R>( |
163 | | - process: Process, |
164 | | - mut runtime_builder: tokio::runtime::Builder, |
165 | | - fut: impl Future<Output = R> + 'a, |
166 | | -) -> R { |
167 | | - ensure_hook(); |
168 | | - |
169 | | - let start_process = process.clone(); |
170 | | - let unpark_process = process.clone(); |
171 | | - let runtime = runtime_builder |
172 | | - // propagate to blocking threads |
173 | | - .on_thread_start(move || { |
174 | | - // assign the process persistently to the thread local. |
175 | | - PROCESS.with(|p| { |
176 | | - if let Some(old_p) = &*p.borrow() { |
177 | | - panic!("current process already set {old_p:?}"); |
178 | | - } |
179 | | - *p.borrow_mut() = Some(start_process.clone()); |
180 | | - // Thread exits will clear the process. |
181 | | - }); |
182 | | - }) |
183 | | - .on_thread_stop(move || { |
184 | | - PROCESS.with(|p| { |
185 | | - *p.borrow_mut() = None; |
186 | | - }); |
187 | | - }) |
188 | | - // propagate to async worker threads |
189 | | - .on_thread_unpark(move || { |
190 | | - // assign the process persistently to the thread local. |
191 | | - PROCESS.with(|p| { |
192 | | - if let Some(old_p) = &*p.borrow() { |
193 | | - panic!("current process already set {old_p:?}"); |
194 | | - } |
195 | | - *p.borrow_mut() = Some(unpark_process.clone()); |
196 | | - // Thread exits will clear the process. |
197 | | - }); |
198 | | - }) |
199 | | - .on_thread_park(move || { |
200 | | - PROCESS.with(|p| { |
201 | | - *p.borrow_mut() = None; |
202 | | - }); |
203 | | - }) |
204 | | - .build() |
205 | | - .unwrap(); |
206 | | - |
207 | | - // The current thread doesn't get hooks run on it. |
208 | | - PROCESS.with(move |p| { |
209 | | - if let Some(old_p) = &*p.borrow() { |
210 | | - panic!("current process already set {old_p:?}"); |
211 | | - } |
212 | | - *p.borrow_mut() = Some(process.clone()); |
213 | | - let result = runtime.block_on(async { |
214 | | - let _guard = crate::cli::log::tracing_subscriber(&process).set_default(); |
215 | | - fut.await |
216 | | - }); |
217 | | - *p.borrow_mut() = None; |
218 | | - result |
219 | | - }) |
220 | | -} |
221 | | - |
222 | | -/// Internal - for the panic hook only |
223 | | -fn clear_process() { |
224 | | - PROCESS.with(|p| p.replace(None)); |
225 | | -} |
226 | | - |
227 | | -thread_local! { |
228 | | - pub(crate) static PROCESS: RefCell<Option<Process>> = const { RefCell::new(None) }; |
229 | | -} |
230 | | - |
231 | 142 | // ----------- real process ----------------- |
232 | 143 |
|
233 | 144 | #[derive(Clone, Debug)] |
|
0 commit comments