use std::fmt::Debug;
use std::ops::{Deref, DerefMut};
use std::panic::AssertUnwindSafe;
use super::{AsyncDrop, AsyncDropGuard};
pub struct SyncDrop<T: Debug + AsyncDrop>(Option<AsyncDropGuard<T>>);
impl<T: Debug + AsyncDrop> SyncDrop<T> {
pub fn new(v: AsyncDropGuard<T>) -> Self {
Self(Some(v))
}
pub fn into_inner_dont_drop(mut self) -> AsyncDropGuard<T> {
self.0.take().expect("Already dropped")
}
pub fn inner(&self) -> &AsyncDropGuard<T> {
self.0.as_ref().expect("Already dropped")
}
}
impl<T: Debug + AsyncDrop> Drop for SyncDrop<T> {
fn drop(&mut self) {
if let Some(mut v) = self.0.take() {
if std::thread::panicking() {
let mut v = AssertUnwindSafe(v);
if let Err(panic) = std::panic::catch_unwind(move || {
futures::executor::block_on(v.async_drop()).unwrap()
}) {
log::error!("Double panic.\nInner panic: {:?}", panic);
eprintln!("Double panic.\nInner panic: {:?}", panic);
}
} else {
futures::executor::block_on(v.async_drop()).unwrap()
}
}
}
}
impl<T: Debug + AsyncDrop> Deref for SyncDrop<T> {
type Target = T;
fn deref(&self) -> &T {
self.0.as_ref().expect("Already dropped")
}
}
impl<T: Debug + AsyncDrop> DerefMut for SyncDrop<T> {
fn deref_mut(&mut self) -> &mut T {
self.0.as_mut().expect("Already dropped")
}
}