diff options
| author | Badel2 <2badel2@gmail.com> | 2022-01-07 17:04:33 +0100 |
|---|---|---|
| committer | Badel2 <2badel2@gmail.com> | 2022-01-08 00:57:59 +0100 |
| commit | 8ef3ce866e2f20bdcc567e2f7012f81ce2e60298 (patch) | |
| tree | 1764db087c7b3bb38aa060ba67b985d4ec63f975 /library/std/src/panicking.rs | |
| parent | 8bdf5c3de6c6e4e01f7f6241cd0f2a606c7486df (diff) | |
| download | rust-8ef3ce866e2f20bdcc567e2f7012f81ce2e60298.tar.gz rust-8ef3ce866e2f20bdcc567e2f7012f81ce2e60298.zip | |
Change panic::update_hook to simplify usage
And to remove possibility of panics while changing the panic handler, because that resulted in a double panic.
Diffstat (limited to 'library/std/src/panicking.rs')
| -rw-r--r-- | library/std/src/panicking.rs | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index cf970dccfc9..19040cb12e0 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -76,6 +76,12 @@ enum Hook { Custom(*mut (dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send)), } +impl Hook { + fn custom(f: impl Fn(&PanicInfo<'_>) + 'static + Sync + Send) -> Self { + Self::Custom(Box::into_raw(Box::new(f))) + } +} + static HOOK_LOCK: StaticRWLock = StaticRWLock::new(); static mut HOOK: Hook = Hook::Default; @@ -180,7 +186,8 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> { } } -/// Atomic combination of [`take_hook`] + [`set_hook`]. +/// Atomic combination of [`take_hook`] and [`set_hook`]. Use this to replace the panic handler with +/// a new panic handler that does something and then executes the old handler. /// /// [`take_hook`]: ./fn.take_hook.html /// [`set_hook`]: ./fn.set_hook.html @@ -189,16 +196,6 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> { /// /// Panics if called from a panicking thread. /// -/// Panics if the provided closure calls any of the functions [`panic::take_hook`], -/// [`panic::set_hook`], or [`panic::update_hook`]. -/// -/// Note: if the provided closure panics, the panic will not be able to be handled, resulting in a -/// double panic that aborts the process with a generic error message. -/// -/// [`panic::take_hook`]: ./fn.take_hook.html -/// [`panic::set_hook`]: ./fn.set_hook.html -/// [`panic::update_hook`]: ./fn.update_hook.html -/// /// # Examples /// /// The following will print the custom message, and then the normal output of panic. @@ -207,11 +204,15 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> { /// #![feature(panic_update_hook)] /// use std::panic; /// -/// panic::update_hook(|prev| { -/// Box::new(move |panic_info| { -/// println!("Print custom message and execute panic handler as usual"); -/// prev(panic_info); -/// }) +/// // Equivalent to +/// // let prev = panic::take_hook(); +/// // panic::set_hook(move |info| { +/// // println!("..."); +/// // prev(info); +/// // ); +/// panic::update_hook(move |prev, info| { +/// println!("Print custom message and execute panic handler as usual"); +/// prev(info); /// }); /// /// panic!("Custom and then normal"); @@ -219,9 +220,10 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> { #[unstable(feature = "panic_update_hook", issue = "92649")] pub fn update_hook<F>(hook_fn: F) where - F: FnOnce( - Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>, - ) -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>, + F: Fn(&(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), &PanicInfo<'_>) + + Sync + + Send + + 'static, { if thread::panicking() { panic!("cannot modify the panic hook from a panicking thread"); @@ -232,13 +234,12 @@ where let old_hook = HOOK; HOOK = Hook::Default; - let hook_for_fn = match old_hook { + let prev = match old_hook { Hook::Default => Box::new(default_hook), Hook::Custom(ptr) => Box::from_raw(ptr), }; - let hook = hook_fn(hook_for_fn); - HOOK = Hook::Custom(Box::into_raw(hook)); + HOOK = Hook::custom(move |info| hook_fn(&prev, info)); drop(guard); } } |
