diff options
Diffstat (limited to 'src/liblog')
| -rw-r--r-- | src/liblog/lib.rs | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 1d865868f18..6ee8ae25f1b 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -177,7 +177,7 @@ use std::mem; use std::os; use std::rt; use std::slice; -use std::sync::{Once, ONCE_INIT}; +use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT}; use regex::Regex; @@ -193,6 +193,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. @@ -281,9 +283,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 !filter.is_match(args.to_string()[]) => 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::<_, &Regex>(n); + if !filter.is_match(args.to_string().as_slice()) { + return + } + } + } } // Completely remove the local logger from TLS in case anyone attempts to @@ -401,9 +412,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, @@ -459,14 +476,15 @@ 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>> = mem::transmute(DIRECTIVES); - DIRECTIVES = 0 as *const Vec<directive::LogDirective>; + DIRECTIVES = 1 as *const Vec<directive::LogDirective>; if !FILTER.is_null() { let _filter: Box<Regex> = mem::transmute(FILTER); - FILTER = 0 as *const _; + FILTER = 1 as *const _; } }); } |
