@@ -184,10 +184,9 @@ use std::old_io::LineBufferedWriter;
184184use std:: old_io;
185185use std:: mem;
186186use std:: env;
187- use std:: ptr;
188187use std:: rt;
189188use std:: slice;
190- use std:: sync:: { Once , ONCE_INIT } ;
189+ use std:: sync:: { Once , ONCE_INIT , StaticMutex , MUTEX_INIT } ;
191190
192191use directive:: LOG_LEVEL_NAMES ;
193192
@@ -203,6 +202,8 @@ pub const MAX_LOG_LEVEL: u32 = 255;
203202/// The default logging level of a crate if no other is specified.
204203const DEFAULT_LOG_LEVEL : u32 = 1 ;
205204
205+ static LOCK : StaticMutex = MUTEX_INIT ;
206+
206207/// An unsafe constant that is the maximum logging level of any module
207208/// specified. This is the first line of defense to determining whether a
208209/// logging statement should be run.
@@ -289,9 +290,18 @@ impl Drop for DefaultLogger {
289290pub fn log ( level : u32 , loc : & ' static LogLocation , args : fmt:: Arguments ) {
290291 // Test the literal string from args against the current filter, if there
291292 // is one.
292- match unsafe { FILTER . as_ref ( ) } {
293- Some ( filter) if !args. to_string ( ) . contains ( & filter[ ..] ) => return ,
294- _ => { }
293+ unsafe {
294+ let _g = LOCK . lock ( ) ;
295+ match FILTER as uint {
296+ 0 => { }
297+ 1 => panic ! ( "cannot log after main thread has exited" ) ,
298+ n => {
299+ let filter = mem:: transmute :: < _ , & String > ( n) ;
300+ if !args. to_string ( ) . contains ( & filter[ ..] ) {
301+ return
302+ }
303+ }
304+ }
295305 }
296306
297307 // Completely remove the local logger from TLS in case anyone attempts to
@@ -373,9 +383,15 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
373383
374384 // This assertion should never get tripped unless we're in an at_exit
375385 // handler after logging has been torn down and a logging attempt was made.
376- assert ! ( unsafe { !DIRECTIVES . is_null( ) } ) ;
377386
378- enabled ( level, module, unsafe { ( * DIRECTIVES ) . iter ( ) } )
387+ let _g = LOCK . lock ( ) ;
388+ unsafe {
389+ assert ! ( DIRECTIVES as uint != 0 ) ;
390+ assert ! ( DIRECTIVES as uint != 1 ,
391+ "cannot log after the main thread has exited" ) ;
392+
393+ enabled ( level, module, ( * DIRECTIVES ) . iter ( ) )
394+ }
379395}
380396
381397fn enabled ( level : u32 ,
@@ -431,14 +447,14 @@ fn init() {
431447
432448 // Schedule the cleanup for the globals for when the runtime exits.
433449 rt:: at_exit ( move || {
450+ let _g = LOCK . lock ( ) ;
434451 assert ! ( !DIRECTIVES . is_null( ) ) ;
435- let _directives: Box < Vec < directive:: LogDirective > > =
436- Box :: from_raw ( DIRECTIVES ) ;
437- DIRECTIVES = ptr:: null_mut ( ) ;
452+ let _directives = Box :: from_raw ( DIRECTIVES ) ;
453+ DIRECTIVES = 1 as * mut _ ;
438454
439455 if !FILTER . is_null ( ) {
440- let _filter: Box < String > = Box :: from_raw ( FILTER ) ;
441- FILTER = 0 as * mut _ ;
456+ let _filter = Box :: from_raw ( FILTER ) ;
457+ FILTER = 1 as * mut _ ;
442458 }
443459 } ) ;
444460 }
0 commit comments