diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-01 10:19:42 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-20 10:56:27 -0700 |
| commit | 1cc9718fdef63476ffdf3f0bcd74b554b083f378 (patch) | |
| tree | 9ab128b25b8bd688a26897a5b8029672d737140e /src/liblog/lib.rs | |
| parent | 46f649c479ce40f3b4590590dda6c2895e8d60f6 (diff) | |
| download | rust-1cc9718fdef63476ffdf3f0bcd74b554b083f378.tar.gz rust-1cc9718fdef63476ffdf3f0bcd74b554b083f378.zip | |
Revert "Revert "std: Re-enable at_exit()""
This reverts commit aec67c2ee0f673ea7b0e21c2fe7e0f26a523d823.
Diffstat (limited to 'src/liblog/lib.rs')
| -rw-r--r-- | src/liblog/lib.rs | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index c634a46888e..4537fc763c9 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -183,10 +183,9 @@ use std::io::{self, Stderr}; use std::io::prelude::*; use std::mem; use std::env; -use std::ptr; use std::rt; use std::slice; -use std::sync::{Once, ONCE_INIT}; +use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT}; use directive::LOG_LEVEL_NAMES; @@ -202,6 +201,8 @@ pub const MAX_LOG_LEVEL: u32 = 255; /// The default logging level of a crate if no other is specified. const DEFAULT_LOG_LEVEL: u32 = 1; +static LOCK: StaticMutex = MUTEX_INIT; + /// An unsafe constant that is the maximum logging level of any module /// specified. This is the first line of defense to determining whether a /// logging statement should be run. @@ -286,9 +287,18 @@ impl Drop for DefaultLogger { pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { // Test the literal string from args against the current filter, if there // is one. - match unsafe { FILTER.as_ref() } { - Some(filter) if !args.to_string().contains(&filter[..]) => return, - _ => {} + unsafe { + let _g = LOCK.lock(); + match FILTER as uint { + 0 => {} + 1 => panic!("cannot log after main thread has exited"), + n => { + let filter = mem::transmute::<_, &String>(n); + if !args.to_string().contains(&filter[..]) { + return + } + } + } } // Completely remove the local logger from TLS in case anyone attempts to @@ -370,9 +380,15 @@ pub fn mod_enabled(level: u32, module: &str) -> bool { // This assertion should never get tripped unless we're in an at_exit // handler after logging has been torn down and a logging attempt was made. - assert!(unsafe { !DIRECTIVES.is_null() }); - enabled(level, module, unsafe { (*DIRECTIVES).iter() }) + let _g = LOCK.lock(); + unsafe { + assert!(DIRECTIVES as uint != 0); + assert!(DIRECTIVES as uint != 1, + "cannot log after the main thread has exited"); + + enabled(level, module, (*DIRECTIVES).iter()) + } } fn enabled(level: u32, @@ -428,14 +444,14 @@ fn init() { // Schedule the cleanup for the globals for when the runtime exits. rt::at_exit(move || { + let _g = LOCK.lock(); assert!(!DIRECTIVES.is_null()); - let _directives: Box<Vec<directive::LogDirective>> = - Box::from_raw(DIRECTIVES); - DIRECTIVES = ptr::null_mut(); + let _directives = Box::from_raw(DIRECTIVES); + DIRECTIVES = 1 as *mut _; if !FILTER.is_null() { - let _filter: Box<String> = Box::from_raw(FILTER); - FILTER = 0 as *mut _; + let _filter = Box::from_raw(FILTER); + FILTER = 1 as *mut _; } }); } |
