diff --git a/postgres/src/lib.rs b/postgres/src/lib.rs index bb716933..a44c565b 100644 --- a/postgres/src/lib.rs +++ b/postgres/src/lib.rs @@ -154,6 +154,8 @@ impl managed::Manager for Manager { } } +impl std::panic::UnwindSafe for Manager {} + #[async_trait] trait Connect: Sync + Send { async fn connect(&self, pg_config: &PgConfig) -> Result<(PgClient, JoinHandle<()>), Error>; diff --git a/src/managed/mod.rs b/src/managed/mod.rs index d6ebd4e3..3a300467 100644 --- a/src/managed/mod.rs +++ b/src/managed/mod.rs @@ -71,6 +71,7 @@ use std::{ future::Future, marker::PhantomData, ops::{Deref, DerefMut}, + panic::{RefUnwindSafe, UnwindSafe}, sync::{ atomic::{AtomicUsize, Ordering}, Arc, Mutex, Weak, @@ -615,6 +616,18 @@ impl>> Pool { } } +impl>> UnwindSafe for Pool +where + M: UnwindSafe, +{ +} + +impl>> RefUnwindSafe for Pool +where + M: UnwindSafe, +{ +} + struct PoolInner { manager: M, slots: Mutex>>, diff --git a/src/unmanaged/mod.rs b/src/unmanaged/mod.rs index 7b899322..a6f6f219 100644 --- a/src/unmanaged/mod.rs +++ b/src/unmanaged/mod.rs @@ -78,6 +78,13 @@ impl Object { impl Drop for Object { fn drop(&mut self) { + // If we're panicking, there is no way to determine whether the object + // we are dropping is the source of the panic. Therefore, always discard + // the object on a panic, and do not return it to the pool. + if std::thread::panicking() { + return; + } + if let Some(obj) = self.obj.take() { if let Some(pool) = self.pool.upgrade() { {