@@ -183,10 +183,9 @@ use std::io::{self, Stderr};
183
183
use std:: io:: prelude:: * ;
184
184
use std:: mem;
185
185
use std:: env;
186
- use std:: ptr;
187
186
use std:: rt;
188
187
use std:: slice;
189
- use std:: sync:: { Once , ONCE_INIT } ;
188
+ use std:: sync:: { Once , ONCE_INIT , StaticMutex , MUTEX_INIT } ;
190
189
191
190
use directive:: LOG_LEVEL_NAMES ;
192
191
@@ -202,6 +201,8 @@ pub const MAX_LOG_LEVEL: u32 = 255;
202
201
/// The default logging level of a crate if no other is specified.
203
202
const DEFAULT_LOG_LEVEL : u32 = 1 ;
204
203
204
+ static LOCK : StaticMutex = MUTEX_INIT ;
205
+
205
206
/// An unsafe constant that is the maximum logging level of any module
206
207
/// specified. This is the first line of defense to determining whether a
207
208
/// logging statement should be run.
@@ -286,9 +287,18 @@ impl Drop for DefaultLogger {
286
287
pub fn log ( level : u32 , loc : & ' static LogLocation , args : fmt:: Arguments ) {
287
288
// Test the literal string from args against the current filter, if there
288
289
// 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
+ }
292
302
}
293
303
294
304
// 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 {
370
380
371
381
// This assertion should never get tripped unless we're in an at_exit
372
382
// handler after logging has been torn down and a logging attempt was made.
373
- assert ! ( unsafe { !DIRECTIVES . is_null( ) } ) ;
374
383
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
+ }
376
392
}
377
393
378
394
fn enabled ( level : u32 ,
@@ -428,14 +444,14 @@ fn init() {
428
444
429
445
// Schedule the cleanup for the globals for when the runtime exits.
430
446
rt:: at_exit ( move || {
447
+ let _g = LOCK . lock ( ) ;
431
448
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 _ ;
435
451
436
452
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 _ ;
439
455
}
440
456
} ) ;
441
457
}
0 commit comments