@@ -184,10 +184,9 @@ use std::old_io::LineBufferedWriter;
184
184
use std:: old_io;
185
185
use std:: mem;
186
186
use std:: env;
187
- use std:: ptr;
188
187
use std:: rt;
189
188
use std:: slice;
190
- use std:: sync:: { Once , ONCE_INIT } ;
189
+ use std:: sync:: { Once , ONCE_INIT , StaticMutex , MUTEX_INIT } ;
191
190
192
191
use directive:: LOG_LEVEL_NAMES ;
193
192
@@ -203,6 +202,8 @@ pub const MAX_LOG_LEVEL: u32 = 255;
203
202
/// The default logging level of a crate if no other is specified.
204
203
const DEFAULT_LOG_LEVEL : u32 = 1 ;
205
204
205
+ static LOCK : StaticMutex = MUTEX_INIT ;
206
+
206
207
/// An unsafe constant that is the maximum logging level of any module
207
208
/// specified. This is the first line of defense to determining whether a
208
209
/// logging statement should be run.
@@ -289,9 +290,18 @@ impl Drop for DefaultLogger {
289
290
pub fn log ( level : u32 , loc : & ' static LogLocation , args : fmt:: Arguments ) {
290
291
// Test the literal string from args against the current filter, if there
291
292
// 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
+ }
295
305
}
296
306
297
307
// 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 {
373
383
374
384
// This assertion should never get tripped unless we're in an at_exit
375
385
// handler after logging has been torn down and a logging attempt was made.
376
- assert ! ( unsafe { !DIRECTIVES . is_null( ) } ) ;
377
386
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
+ }
379
395
}
380
396
381
397
fn enabled ( level : u32 ,
@@ -431,14 +447,14 @@ fn init() {
431
447
432
448
// Schedule the cleanup for the globals for when the runtime exits.
433
449
rt:: at_exit ( move || {
450
+ let _g = LOCK . lock ( ) ;
434
451
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 _ ;
438
454
439
455
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 _ ;
442
458
}
443
459
} ) ;
444
460
}
0 commit comments