async_drop_guard/
sync_drop.rs1use std::fmt::Debug;
2use std::ops::{Deref, DerefMut};
3use std::panic::AssertUnwindSafe;
4
5use super::{AsyncDrop, AsyncDropGuard};
6
7pub struct SyncDrop<T: Debug + AsyncDrop>(Option<AsyncDropGuard<T>>);
12
13impl<T: Debug + AsyncDrop> SyncDrop<T> {
14 pub fn new(v: AsyncDropGuard<T>) -> Self {
15 Self(Some(v))
16 }
17
18 pub fn into_inner_dont_drop(mut self) -> AsyncDropGuard<T> {
19 self.0.take().expect("Already dropped")
20 }
21
22 pub fn inner(&self) -> &AsyncDropGuard<T> {
23 self.0.as_ref().expect("Already dropped")
24 }
25}
26
27impl<T: Debug + AsyncDrop> Drop for SyncDrop<T> {
28 fn drop(&mut self) {
29 if let Some(mut v) = self.0.take() {
30 if std::thread::panicking() {
31 let mut v = AssertUnwindSafe(v);
34 if let Err(panic) = std::panic::catch_unwind(move || {
38 futures::executor::block_on(v.async_drop()).unwrap()
39 }) {
40 log::error!("Double panic.\nInner panic: {:?}", panic);
41 eprintln!("Double panic.\nInner panic: {:?}", panic);
42 }
43 } else {
44 futures::executor::block_on(v.async_drop()).unwrap()
45 }
46 }
47 }
48}
49
50impl<T: Debug + AsyncDrop> Deref for SyncDrop<T> {
51 type Target = T;
52 fn deref(&self) -> &T {
53 self.0.as_ref().expect("Already dropped")
54 }
55}
56
57impl<T: Debug + AsyncDrop> DerefMut for SyncDrop<T> {
58 fn deref_mut(&mut self) -> &mut T {
59 self.0.as_mut().expect("Already dropped")
60 }
61}