@@ -16,7 +16,7 @@ use cmp;
16
16
use fmt;
17
17
use io:: lazy:: Lazy ;
18
18
use io:: { self , BufReader , LineWriter } ;
19
- use sync:: { Arc , Mutex , MutexGuard } ;
19
+ use sync:: { Arc , Mutex , ReentrantMutex , MutexGuard , ReentrantMutexGuard } ;
20
20
use sys:: stdio;
21
21
22
22
/// Stdout used by print! and println! macros
@@ -210,7 +210,7 @@ pub struct Stdout {
210
210
// FIXME: this should be LineWriter or BufWriter depending on the state of
211
211
// stdout (tty or not). Note that if this is not line buffered it
212
212
// should also flush-on-panic or some form of flush-on-abort.
213
- inner : Arc < Mutex < LineWriter < StdoutRaw > > > ,
213
+ inner : Arc < ReentrantMutex < LineWriter < StdoutRaw > > > ,
214
214
}
215
215
216
216
/// A locked reference to the a `Stdout` handle.
@@ -219,7 +219,7 @@ pub struct Stdout {
219
219
/// method on `Stdout`.
220
220
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
221
221
pub struct StdoutLock < ' a > {
222
- inner : MutexGuard < ' a , LineWriter < StdoutRaw > > ,
222
+ inner : ReentrantMutexGuard < ' a , LineWriter < StdoutRaw > > ,
223
223
}
224
224
225
225
/// Constructs a new reference to the standard output of the current process.
@@ -231,13 +231,13 @@ pub struct StdoutLock<'a> {
231
231
/// The returned handle implements the `Write` trait.
232
232
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
233
233
pub fn stdout ( ) -> Stdout {
234
- static INSTANCE : Lazy < Mutex < LineWriter < StdoutRaw > > > = lazy_init ! ( stdout_init) ;
234
+ static INSTANCE : Lazy < ReentrantMutex < LineWriter < StdoutRaw > > > = lazy_init ! ( stdout_init) ;
235
235
return Stdout {
236
236
inner : INSTANCE . get ( ) . expect ( "cannot access stdout during shutdown" ) ,
237
237
} ;
238
238
239
- fn stdout_init ( ) -> Arc < Mutex < LineWriter < StdoutRaw > > > {
240
- Arc :: new ( Mutex :: new ( LineWriter :: new ( stdout_raw ( ) ) ) )
239
+ fn stdout_init ( ) -> Arc < ReentrantMutex < LineWriter < StdoutRaw > > > {
240
+ Arc :: new ( ReentrantMutex :: new ( LineWriter :: new ( stdout_raw ( ) ) ) )
241
241
}
242
242
}
243
243
@@ -264,23 +264,26 @@ impl Write for Stdout {
264
264
fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
265
265
self . lock ( ) . write_all ( buf)
266
266
}
267
- // Don't override write_fmt as it's possible to run arbitrary code during a
268
- // write_fmt, allowing the possibility of a recursive lock (aka deadlock)
267
+ fn write_fmt ( & mut self , args : fmt:: Arguments ) -> io:: Result < ( ) > {
268
+ self . lock ( ) . write_fmt ( args)
269
+ }
269
270
}
270
271
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
271
272
impl < ' a > Write for StdoutLock < ' a > {
272
273
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
273
- self . inner . write ( & buf[ ..cmp:: min ( buf. len ( ) , OUT_MAX ) ] )
274
+ self . inner . borrow_mut ( ) . write ( & buf[ ..cmp:: min ( buf. len ( ) , OUT_MAX ) ] )
275
+ }
276
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
277
+ self . inner . borrow_mut ( ) . flush ( )
274
278
}
275
- fn flush ( & mut self ) -> io:: Result < ( ) > { self . inner . flush ( ) }
276
279
}
277
280
278
281
/// A handle to the standard error stream of a process.
279
282
///
280
283
/// For more information, see `stderr`
281
284
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
282
285
pub struct Stderr {
283
- inner : Arc < Mutex < StderrRaw > > ,
286
+ inner : Arc < ReentrantMutex < StderrRaw > > ,
284
287
}
285
288
286
289
/// A locked reference to the a `Stderr` handle.
@@ -289,7 +292,7 @@ pub struct Stderr {
289
292
/// method on `Stderr`.
290
293
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
291
294
pub struct StderrLock < ' a > {
292
- inner : MutexGuard < ' a , StderrRaw > ,
295
+ inner : ReentrantMutexGuard < ' a , StderrRaw > ,
293
296
}
294
297
295
298
/// Constructs a new reference to the standard error stream of a process.
@@ -300,13 +303,13 @@ pub struct StderrLock<'a> {
300
303
/// The returned handle implements the `Write` trait.
301
304
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
302
305
pub fn stderr ( ) -> Stderr {
303
- static INSTANCE : Lazy < Mutex < StderrRaw > > = lazy_init ! ( stderr_init) ;
306
+ static INSTANCE : Lazy < ReentrantMutex < StderrRaw > > = lazy_init ! ( stderr_init) ;
304
307
return Stderr {
305
308
inner : INSTANCE . get ( ) . expect ( "cannot access stderr during shutdown" ) ,
306
309
} ;
307
310
308
- fn stderr_init ( ) -> Arc < Mutex < StderrRaw > > {
309
- Arc :: new ( Mutex :: new ( stderr_raw ( ) ) )
311
+ fn stderr_init ( ) -> Arc < ReentrantMutex < StderrRaw > > {
312
+ Arc :: new ( ReentrantMutex :: new ( stderr_raw ( ) ) )
310
313
}
311
314
}
312
315
@@ -333,14 +336,18 @@ impl Write for Stderr {
333
336
fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
334
337
self . lock ( ) . write_all ( buf)
335
338
}
336
- // Don't override write_fmt for the same reasons as Stdout
339
+ fn write_fmt ( & mut self , args : fmt:: Arguments ) -> io:: Result < ( ) > {
340
+ self . lock ( ) . write_fmt ( args)
341
+ }
337
342
}
338
343
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
339
344
impl < ' a > Write for StderrLock < ' a > {
340
345
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
341
- self . inner . write ( & buf[ ..cmp:: min ( buf. len ( ) , OUT_MAX ) ] )
346
+ self . inner . borrow_mut ( ) . write ( & buf[ ..cmp:: min ( buf. len ( ) , OUT_MAX ) ] )
347
+ }
348
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
349
+ self . inner . borrow_mut ( ) . flush ( )
342
350
}
343
- fn flush ( & mut self ) -> io:: Result < ( ) > { self . inner . flush ( ) }
344
351
}
345
352
346
353
/// Resets the task-local stderr handle to the specified writer
0 commit comments