@@ -16,7 +16,7 @@ use cmp;
1616use fmt;
1717use io:: lazy:: Lazy ;
1818use io:: { self , BufReader , LineWriter } ;
19- use sync:: { Arc , Mutex , MutexGuard } ;
19+ use sync:: { Arc , ReentrantMutex , ReentrantMutexGuard } ;
2020use sys:: stdio;
2121
2222/// Stdout used by print! and println! macros
@@ -96,7 +96,7 @@ impl Write for StderrRaw {
9696/// of `Stdin` must be executed with care.
9797#[ stable( feature = "rust1" , since = "1.0.0" ) ]
9898pub struct Stdin {
99- inner : Arc < Mutex < BufReader < StdinRaw > > > ,
99+ inner : Arc < ReentrantMutex < BufReader < StdinRaw > > > ,
100100}
101101
102102/// A locked reference to the a `Stdin` handle.
@@ -105,7 +105,7 @@ pub struct Stdin {
105105/// constructed via the `lock` method on `Stdin`.
106106#[ stable( feature = "rust1" , since = "1.0.0" ) ]
107107pub struct StdinLock < ' a > {
108- inner : MutexGuard < ' a , BufReader < StdinRaw > > ,
108+ inner : ReentrantMutexGuard < ' a , BufReader < StdinRaw > > ,
109109}
110110
111111/// Create a new handle to the global standard input stream of this process.
@@ -119,17 +119,17 @@ pub struct StdinLock<'a> {
119119/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
120120#[ stable( feature = "rust1" , since = "1.0.0" ) ]
121121pub fn stdin ( ) -> Stdin {
122- static INSTANCE : Lazy < Mutex < BufReader < StdinRaw > > > = lazy_init ! ( stdin_init) ;
122+ static INSTANCE : Lazy < ReentrantMutex < BufReader < StdinRaw > > > = lazy_init ! ( stdin_init) ;
123123 return Stdin {
124124 inner : INSTANCE . get ( ) . expect ( "cannot access stdin during shutdown" ) ,
125125 } ;
126126
127- fn stdin_init ( ) -> Arc < Mutex < BufReader < StdinRaw > > > {
127+ fn stdin_init ( ) -> Arc < ReentrantMutex < BufReader < StdinRaw > > > {
128128 // The default buffer capacity is 64k, but apparently windows
129129 // doesn't like 64k reads on stdin. See #13304 for details, but the
130130 // idea is that on windows we use a slightly smaller buffer that's
131131 // been seen to be acceptable.
132- Arc :: new ( Mutex :: new ( if cfg ! ( windows) {
132+ Arc :: new ( ReentrantMutex :: new ( if cfg ! ( windows) {
133133 BufReader :: with_capacity ( 8 * 1024 , stdin_raw ( ) )
134134 } else {
135135 BufReader :: new ( stdin_raw ( ) )
@@ -210,7 +210,7 @@ pub struct Stdout {
210210 // FIXME: this should be LineWriter or BufWriter depending on the state of
211211 // stdout (tty or not). Note that if this is not line buffered it
212212 // should also flush-on-panic or some form of flush-on-abort.
213- inner : Arc < Mutex < LineWriter < StdoutRaw > > > ,
213+ inner : Arc < ReentrantMutex < LineWriter < StdoutRaw > > > ,
214214}
215215
216216/// A locked reference to the a `Stdout` handle.
@@ -219,7 +219,7 @@ pub struct Stdout {
219219/// method on `Stdout`.
220220#[ stable( feature = "rust1" , since = "1.0.0" ) ]
221221pub struct StdoutLock < ' a > {
222- inner : MutexGuard < ' a , LineWriter < StdoutRaw > > ,
222+ inner : ReentrantMutexGuard < ' a , LineWriter < StdoutRaw > > ,
223223}
224224
225225/// Constructs a new reference to the standard output of the current process.
@@ -231,13 +231,13 @@ pub struct StdoutLock<'a> {
231231/// The returned handle implements the `Write` trait.
232232#[ stable( feature = "rust1" , since = "1.0.0" ) ]
233233pub 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) ;
235235 return Stdout {
236236 inner : INSTANCE . get ( ) . expect ( "cannot access stdout during shutdown" ) ,
237237 } ;
238238
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 ( ) ) ) )
241241 }
242242}
243243
@@ -264,8 +264,9 @@ impl Write for Stdout {
264264 fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
265265 self . lock ( ) . write_all ( buf)
266266 }
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+ }
269270}
270271#[ stable( feature = "rust1" , since = "1.0.0" ) ]
271272impl < ' a > Write for StdoutLock < ' a > {
@@ -280,7 +281,7 @@ impl<'a> Write for StdoutLock<'a> {
280281/// For more information, see `stderr`
281282#[ stable( feature = "rust1" , since = "1.0.0" ) ]
282283pub struct Stderr {
283- inner : Arc < Mutex < StderrRaw > > ,
284+ inner : Arc < ReentrantMutex < StderrRaw > > ,
284285}
285286
286287/// A locked reference to the a `Stderr` handle.
@@ -289,7 +290,7 @@ pub struct Stderr {
289290/// method on `Stderr`.
290291#[ stable( feature = "rust1" , since = "1.0.0" ) ]
291292pub struct StderrLock < ' a > {
292- inner : MutexGuard < ' a , StderrRaw > ,
293+ inner : ReentrantMutexGuard < ' a , StderrRaw > ,
293294}
294295
295296/// Constructs a new reference to the standard error stream of a process.
@@ -300,13 +301,13 @@ pub struct StderrLock<'a> {
300301/// The returned handle implements the `Write` trait.
301302#[ stable( feature = "rust1" , since = "1.0.0" ) ]
302303pub fn stderr ( ) -> Stderr {
303- static INSTANCE : Lazy < Mutex < StderrRaw > > = lazy_init ! ( stderr_init) ;
304+ static INSTANCE : Lazy < ReentrantMutex < StderrRaw > > = lazy_init ! ( stderr_init) ;
304305 return Stderr {
305306 inner : INSTANCE . get ( ) . expect ( "cannot access stderr during shutdown" ) ,
306307 } ;
307308
308- fn stderr_init ( ) -> Arc < Mutex < StderrRaw > > {
309- Arc :: new ( Mutex :: new ( stderr_raw ( ) ) )
309+ fn stderr_init ( ) -> Arc < ReentrantMutex < StderrRaw > > {
310+ Arc :: new ( ReentrantMutex :: new ( stderr_raw ( ) ) )
310311 }
311312}
312313
@@ -333,7 +334,9 @@ impl Write for Stderr {
333334 fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
334335 self . lock ( ) . write_all ( buf)
335336 }
336- // Don't override write_fmt for the same reasons as Stdout
337+ fn write_fmt ( & mut self , args : fmt:: Arguments ) -> io:: Result < ( ) > {
338+ self . lock ( ) . write_fmt ( args)
339+ }
337340}
338341#[ stable( feature = "rust1" , since = "1.0.0" ) ]
339342impl < ' a > Write for StderrLock < ' a > {
0 commit comments