@@ -183,10 +183,9 @@ use std::io::{self, Stderr};
183183use std:: io:: prelude:: * ;
184184use std:: mem;
185185use std:: env;
186- use std:: ptr;
187186use std:: rt;
188187use std:: slice;
189- use std:: sync:: { Once , ONCE_INIT } ;
188+ use std:: sync:: { Once , ONCE_INIT , StaticMutex , MUTEX_INIT } ;
190189
191190use directive:: LOG_LEVEL_NAMES ;
192191
@@ -202,6 +201,8 @@ pub const MAX_LOG_LEVEL: u32 = 255;
202201/// The default logging level of a crate if no other is specified.
203202const DEFAULT_LOG_LEVEL : u32 = 1 ;
204203
204+ static LOCK : StaticMutex = MUTEX_INIT ;
205+
205206/// An unsafe constant that is the maximum logging level of any module
206207/// specified. This is the first line of defense to determining whether a
207208/// logging statement should be run.
@@ -286,9 +287,18 @@ impl Drop for DefaultLogger {
286287pub fn log ( level : u32 , loc : & ' static LogLocation , args : fmt:: Arguments ) {
287288 // Test the literal string from args against the current filter, if there
288289 // is one.
289- match unsafe { FILTER . as_ref ( ) } {
290- Some ( filter) if !args. to_string ( ) . contains ( & filter[ ..] ) => return ,
291- _ => { }
290+ unsafe {
291+ let _g = LOCK . lock ( ) ;
292+ match FILTER as uint {
293+ 0 => { }
294+ 1 => panic ! ( "cannot log after main thread has exited" ) ,
295+ n => {
296+ let filter = mem:: transmute :: < _ , & String > ( n) ;
297+ if !args. to_string ( ) . contains ( & filter[ ..] ) {
298+ return
299+ }
300+ }
301+ }
292302 }
293303
294304 // 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 {
370380
371381 // This assertion should never get tripped unless we're in an at_exit
372382 // handler after logging has been torn down and a logging attempt was made.
373- assert ! ( unsafe { !DIRECTIVES . is_null( ) } ) ;
374383
375- enabled ( level, module, unsafe { ( * DIRECTIVES ) . iter ( ) } )
384+ let _g = LOCK . lock ( ) ;
385+ unsafe {
386+ assert ! ( DIRECTIVES as uint != 0 ) ;
387+ assert ! ( DIRECTIVES as uint != 1 ,
388+ "cannot log after the main thread has exited" ) ;
389+
390+ enabled ( level, module, ( * DIRECTIVES ) . iter ( ) )
391+ }
376392}
377393
378394fn enabled ( level : u32 ,
@@ -428,14 +444,14 @@ fn init() {
428444
429445 // Schedule the cleanup for the globals for when the runtime exits.
430446 rt:: at_exit ( move || {
447+ let _g = LOCK . lock ( ) ;
431448 assert ! ( !DIRECTIVES . is_null( ) ) ;
432- let _directives: Box < Vec < directive:: LogDirective > > =
433- Box :: from_raw ( DIRECTIVES ) ;
434- DIRECTIVES = ptr:: null_mut ( ) ;
449+ let _directives = Box :: from_raw ( DIRECTIVES ) ;
450+ DIRECTIVES = 1 as * mut _ ;
435451
436452 if !FILTER . is_null ( ) {
437- let _filter: Box < String > = Box :: from_raw ( FILTER ) ;
438- FILTER = 0 as * mut _ ;
453+ let _filter = Box :: from_raw ( FILTER ) ;
454+ FILTER = 1 as * mut _ ;
439455 }
440456 } ) ;
441457 }
0 commit comments