diff --git a/tokio/src/sync/watch.rs b/tokio/src/sync/watch.rs index fa1ad05139c..89ac6891cb4 100644 --- a/tokio/src/sync/watch.rs +++ b/tokio/src/sync/watch.rs @@ -772,8 +772,24 @@ impl Receiver { let has_changed = self.version != new_version; self.version = new_version; - if (!closed || has_changed) && f(&inner) { - return Ok(Ref { inner, has_changed }); + if !closed || has_changed { + let result = + panic::catch_unwind(panic::AssertUnwindSafe(|| f(&inner))); + match result { + Ok(true) => { + return Ok(Ref { inner, has_changed }); + } + Ok(false) => { + // Skip the value. + } + Err(panicked) => { + // Drop the read-lock to avoid poisoning it. + drop(inner); + // Forward the panic to the caller. + panic::resume_unwind(panicked); + // Unreachable + } + }; } }