@@ -21,7 +21,6 @@ use prelude::v1::*;
2121use io:: prelude:: * ;
2222
2323use any:: Any ;
24- use cell:: Cell ;
2524use cell:: RefCell ;
2625use fmt;
2726use intrinsics;
@@ -39,8 +38,6 @@ thread_local! {
3938 }
4039}
4140
42- thread_local ! { pub static PANIC_COUNT : Cell <usize > = Cell :: new( 0 ) }
43-
4441// Binary interface to the panic runtime that the standard library depends on.
4542//
4643// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
@@ -187,7 +184,7 @@ fn default_hook(info: &PanicInfo) {
187184 // for this panic. Otherwise only print it if logging is enabled.
188185 #[ cfg( any( not( cargobuild) , feature = "backtrace" ) ) ]
189186 let log_backtrace = {
190- let panics = PANIC_COUNT . with ( |c| c . get ( ) ) ;
187+ let panics = update_panic_count ( 0 ) ;
191188
192189 panics >= 2 || backtrace:: log_enabled ( )
193190 } ;
@@ -238,6 +235,24 @@ fn default_hook(info: &PanicInfo) {
238235 }
239236}
240237
238+
239+ #[ cfg( not( test) ) ]
240+ #[ doc( hidden) ]
241+ #[ unstable( feature = "update_panic_count" , issue = "0" ) ]
242+ pub fn update_panic_count ( amt : isize ) -> usize {
243+ use cell:: Cell ;
244+ thread_local ! { static PANIC_COUNT : Cell <usize > = Cell :: new( 0 ) }
245+
246+ PANIC_COUNT . with ( |c| {
247+ let next = ( c. get ( ) as isize + amt) as usize ;
248+ c. set ( next) ;
249+ return next
250+ } )
251+ }
252+
253+ #[ cfg( test) ]
254+ pub use realstd:: rt:: update_panic_count;
255+
241256/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
242257pub unsafe fn try < R , F : FnOnce ( ) -> R > ( f : F ) -> Result < R , Box < Any + Send > > {
243258 let mut slot = None ;
@@ -260,18 +275,15 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
260275 if r == 0 {
261276 ret = Ok ( ( ) ) ;
262277 } else {
263- PANIC_COUNT . with ( |s| {
264- let prev = s. get ( ) ;
265- s. set ( prev - 1 ) ;
266- } ) ;
278+ update_panic_count ( -1 ) ;
267279 ret = Err ( mem:: transmute ( raw:: TraitObject {
268280 data : any_data as * mut _ ,
269281 vtable : any_vtable as * mut _ ,
270282 } ) ) ;
271283 }
272284 }
273285
274- debug_assert ! ( PANIC_COUNT . with ( |c| c . get ( ) == 0 ) ) ;
286+ debug_assert ! ( update_panic_count ( 0 ) == 0 ) ;
275287 return ret. map ( |( ) | {
276288 slot. take ( ) . unwrap ( )
277289 } ) ;
@@ -287,7 +299,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
287299
288300/// Determines whether the current thread is unwinding because of panic.
289301pub fn panicking ( ) -> bool {
290- PANIC_COUNT . with ( |c| c . get ( ) != 0 )
302+ update_panic_count ( 0 ) != 0
291303}
292304
293305/// Entry point of panic from the libcore crate.
@@ -352,18 +364,14 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
352364 file_line : & ( & ' static str , u32 ) ) -> ! {
353365 let ( file, line) = * file_line;
354366
355- let panics = PANIC_COUNT . with ( |c| {
356- let prev = c. get ( ) ;
357- c. set ( prev + 1 ) ;
358- prev
359- } ) ;
367+ let panics = update_panic_count ( 1 ) ;
360368
361369 // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
362370 // the panic hook probably triggered the last panic, otherwise the
363371 // double-panic check would have aborted the process. In this case abort the
364372 // process real quickly as we don't want to try calling it again as it'll
365373 // probably just panic again.
366- if panics > 1 {
374+ if panics > 2 {
367375 util:: dumb_print ( format_args ! ( "thread panicked while processing \
368376 panic. aborting.\n ") ) ;
369377 unsafe { intrinsics:: abort ( ) }
@@ -385,7 +393,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
385393 HOOK_LOCK . read_unlock ( ) ;
386394 }
387395
388- if panics > 0 {
396+ if panics > 1 {
389397 // If a thread panics while it's already unwinding then we
390398 // have limited options. Currently our preference is to
391399 // just abort. In the future we may consider resuming
@@ -400,11 +408,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
400408
401409/// Shim around rust_panic. Called by resume_unwind.
402410pub fn update_count_then_panic ( msg : Box < Any + Send > ) -> ! {
403- PANIC_COUNT . with ( |c| {
404- let prev = c. get ( ) ;
405- c. set ( prev + 1 ) ;
406- } ) ;
407-
411+ update_panic_count ( 1 ) ;
408412 rust_panic ( msg)
409413}
410414
0 commit comments