@@ -92,23 +92,6 @@ pub mod imp;
9292#[ path = "gcc.rs" ] #[ doc( hidden) ]
9393pub mod imp;
9494
95- pub type Callback = fn ( msg : & ( Any + Send ) , file : & ' static str , line : u32 ) ;
96-
97- // Variables used for invoking callbacks when a thread starts to unwind.
98- //
99- // For more information, see below.
100- const MAX_CALLBACKS : usize = 16 ;
101- static CALLBACKS : [ atomic:: AtomicUsize ; MAX_CALLBACKS ] =
102- [ atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
103- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
104- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
105- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
106- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
107- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
108- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ,
109- atomic:: AtomicUsize :: new ( 0 ) , atomic:: AtomicUsize :: new ( 0 ) ] ;
110- static CALLBACK_CNT : atomic:: AtomicUsize = atomic:: AtomicUsize :: new ( 0 ) ;
111-
11295thread_local ! { static PANICKING : Cell <bool > = Cell :: new( false ) }
11396
11497/// Invoke a closure, capturing the cause of panic if one occurs.
@@ -246,45 +229,11 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> !
246229#[ inline( never) ] #[ cold] // this is the slow path, please never inline this
247230fn begin_unwind_inner ( msg : Box < Any + Send > ,
248231 file_line : & ( & ' static str , u32 ) ) -> ! {
249- // Make sure the default failure handler is registered before we look at the
250- // callbacks. We also use a raw sys-based mutex here instead of a
251- // `std::sync` one as accessing TLS can cause weird recursive problems (and
252- // we don't need poison checking).
253- unsafe {
254- static LOCK : Mutex = Mutex :: new ( ) ;
255- static mut INIT : bool = false ;
256- LOCK . lock ( ) ;
257- if !INIT {
258- register ( panicking:: on_panic) ;
259- INIT = true ;
260- }
261- LOCK . unlock ( ) ;
262- }
232+ let ( file, line) = * file_line;
263233
264- // First, invoke call the user-defined callbacks triggered on thread panic.
265- //
266- // By the time that we see a callback has been registered (by reading
267- // MAX_CALLBACKS), the actual callback itself may have not been stored yet,
268- // so we just chalk it up to a race condition and move on to the next
269- // callback. Additionally, CALLBACK_CNT may briefly be higher than
270- // MAX_CALLBACKS, so we're sure to clamp it as necessary.
271- let callbacks = {
272- let amt = CALLBACK_CNT . load ( Ordering :: SeqCst ) ;
273- & CALLBACKS [ ..cmp:: min ( amt, MAX_CALLBACKS ) ]
274- } ;
275- for cb in callbacks {
276- match cb. load ( Ordering :: SeqCst ) {
277- 0 => { }
278- n => {
279- let f: Callback = unsafe { mem:: transmute ( n) } ;
280- let ( file, line) = * file_line;
281- f ( & * msg, file, line) ;
282- }
283- }
284- } ;
234+ // First, invoke the default panic handler.
235+ panicking:: on_panic ( & * msg, file, line) ;
285236
286- // Now that we've run all the necessary unwind callbacks, we actually
287- // perform the unwinding.
288237 if panicking ( ) {
289238 // If a thread panics while it's already unwinding then we
290239 // have limited options. Currently our preference is to
@@ -295,34 +244,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>,
295244 unsafe { intrinsics:: abort ( ) }
296245 }
297246 PANICKING . with ( |s| s. set ( true ) ) ;
298- rust_panic ( msg) ;
299- }
300247
301- /// Register a callback to be invoked when a thread unwinds.
302- ///
303- /// This is an unsafe and experimental API which allows for an arbitrary
304- /// callback to be invoked when a thread panics. This callback is invoked on both
305- /// the initial unwinding and a double unwinding if one occurs. Additionally,
306- /// the local `Thread` will be in place for the duration of the callback, and
307- /// the callback must ensure that it remains in place once the callback returns.
308- ///
309- /// Only a limited number of callbacks can be registered, and this function
310- /// returns whether the callback was successfully registered or not. It is not
311- /// currently possible to unregister a callback once it has been registered.
312- pub unsafe fn register ( f : Callback ) -> bool {
313- match CALLBACK_CNT . fetch_add ( 1 , Ordering :: SeqCst ) {
314- // The invocation code has knowledge of this window where the count has
315- // been incremented, but the callback has not been stored. We're
316- // guaranteed that the slot we're storing into is 0.
317- n if n < MAX_CALLBACKS => {
318- let prev = CALLBACKS [ n] . swap ( mem:: transmute ( f) , Ordering :: SeqCst ) ;
319- rtassert ! ( prev == 0 ) ;
320- true
321- }
322- // If we accidentally bumped the count too high, pull it back.
323- _ => {
324- CALLBACK_CNT . store ( MAX_CALLBACKS , Ordering :: SeqCst ) ;
325- false
326- }
327- }
248+ // Finally, perform the unwinding.
249+ rust_panic ( msg) ;
328250}
0 commit comments