11// Copyright (c) 2017-present, PingCAP, Inc. Licensed under Apache-2.0.
22
3- use std:: panic:: { self , AssertUnwindSafe } ;
3+ use std:: {
4+ panic:: { self , AssertUnwindSafe } ,
5+ sync:: Arc ,
6+ } ;
47
58use raft:: eraftpb:: Entry ;
69
@@ -63,22 +66,18 @@ where
6366}
6467
6568pub struct PanicGuard {
66- prev_hook : * mut ( dyn Fn ( & panic:: PanicHookInfo < ' _ > ) + Sync + Send + ' static ) ,
69+ prev_hook : Arc < dyn Fn ( & panic:: PanicHookInfo < ' _ > ) + Sync + Send + ' static > ,
6770}
6871
69- struct PointerHolder < T : ?Sized > ( * mut T ) ;
70-
71- unsafe impl < T : Send + ?Sized > Send for PointerHolder < T > { }
72- unsafe impl < T : Sync + ?Sized > Sync for PointerHolder < T > { }
73-
7472impl PanicGuard {
7573 pub fn with_prompt ( s : String ) -> Self {
76- let prev_hook = Box :: into_raw ( panic:: take_hook ( ) ) ;
77- let sendable_prev_hook = PointerHolder ( prev_hook) ;
74+ let prev_hook: Arc < dyn Fn ( & panic:: PanicHookInfo < ' _ > ) + Sync + Send + ' static > =
75+ Arc :: from ( panic:: take_hook ( ) ) ;
76+ let prev_hook_for_hook = Arc :: clone ( & prev_hook) ;
7877 // FIXME: Use thread local hook.
7978 panic:: set_hook ( Box :: new ( move |info| {
8079 eprintln ! ( "{s}" ) ;
81- unsafe { ( * sendable_prev_hook . 0 ) ( info) } ;
80+ prev_hook_for_hook ( info) ;
8281 } ) ) ;
8382 PanicGuard { prev_hook }
8483 }
@@ -88,9 +87,8 @@ impl Drop for PanicGuard {
8887 fn drop ( & mut self ) {
8988 if !std:: thread:: panicking ( ) {
9089 let _ = panic:: take_hook ( ) ;
91- unsafe {
92- panic:: set_hook ( Box :: from_raw ( self . prev_hook ) ) ;
93- }
90+ let prev_hook = Arc :: clone ( & self . prev_hook ) ;
91+ panic:: set_hook ( Box :: new ( move |info| prev_hook ( info) ) ) ;
9492 }
9593 }
9694}
0 commit comments