@@ -5,10 +5,9 @@ mod tests;
55
66use crate :: io:: prelude:: * ;
77
8- use crate :: cell:: { Cell , RefCell } ;
8+ use crate :: cell:: { Cell , RefCell , RefMut } ;
99use crate :: fmt;
1010use crate :: io:: { self , BufReader , IoSlice , IoSliceMut , LineWriter , Lines } ;
11- use crate :: pin:: Pin ;
1211use crate :: sync:: atomic:: { AtomicBool , Ordering } ;
1312use crate :: sync:: { Arc , Mutex , MutexGuard , OnceLock } ;
1413use crate :: sys:: stdio;
@@ -526,7 +525,7 @@ pub struct Stdout {
526525 // FIXME: this should be LineWriter or BufWriter depending on the state of
527526 // stdout (tty or not). Note that if this is not line buffered it
528527 // should also flush-on-panic or some form of flush-on-abort.
529- inner : Pin < & ' static ReentrantMutex < RefCell < LineWriter < StdoutRaw > > > > ,
528+ inner : & ' static ReentrantMutex < RefCell < Option < LineWriter < StdoutRaw > > > > ,
530529}
531530
532531/// A locked reference to the [`Stdout`] handle.
@@ -548,10 +547,11 @@ pub struct Stdout {
548547#[ must_use = "if unused stdout will immediately unlock" ]
549548#[ stable( feature = "rust1" , since = "1.0.0" ) ]
550549pub struct StdoutLock < ' a > {
551- inner : ReentrantMutexGuard < ' a , RefCell < LineWriter < StdoutRaw > > > ,
550+ inner : ReentrantMutexGuard < ' a , RefCell < Option < LineWriter < StdoutRaw > > > > ,
552551}
553552
554- static STDOUT : OnceLock < ReentrantMutex < RefCell < LineWriter < StdoutRaw > > > > = OnceLock :: new ( ) ;
553+ static STDOUT : ReentrantMutex < RefCell < Option < LineWriter < StdoutRaw > > > > =
554+ ReentrantMutex :: new ( RefCell :: new ( None ) ) ;
555555
556556/// Constructs a new handle to the standard output of the current process.
557557///
@@ -602,25 +602,18 @@ static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLo
602602#[ must_use]
603603#[ stable( feature = "rust1" , since = "1.0.0" ) ]
604604pub fn stdout ( ) -> Stdout {
605- Stdout {
606- inner : Pin :: static_ref ( & STDOUT ) . get_or_init_pin (
607- || unsafe { ReentrantMutex :: new ( RefCell :: new ( LineWriter :: new ( stdout_raw ( ) ) ) ) } ,
608- |mutex| unsafe { mutex. init ( ) } ,
609- ) ,
610- }
605+ Stdout { inner : & STDOUT }
611606}
612607
613608pub fn cleanup ( ) {
614- if let Some ( instance) = STDOUT . get ( ) {
615- // Flush the data and disable buffering during shutdown
616- // by replacing the line writer by one with zero
617- // buffering capacity.
618- // We use try_lock() instead of lock(), because someone
619- // might have leaked a StdoutLock, which would
620- // otherwise cause a deadlock here.
621- if let Some ( lock) = Pin :: static_ref ( instance) . try_lock ( ) {
622- * lock. borrow_mut ( ) = LineWriter :: with_capacity ( 0 , stdout_raw ( ) ) ;
623- }
609+ // Flush the data and disable buffering during shutdown
610+ // by replacing the line writer by one with zero
611+ // buffering capacity.
612+ // We use try_lock() instead of lock(), because someone
613+ // might have leaked a StdoutLock, which would
614+ // otherwise cause a deadlock here.
615+ if let Some ( lock) = STDOUT . try_lock ( ) {
616+ * lock. borrow_mut ( ) = Some ( LineWriter :: with_capacity ( 0 , stdout_raw ( ) ) ) ;
624617 }
625618}
626619
@@ -712,26 +705,38 @@ impl Write for &Stdout {
712705 }
713706}
714707
708+ impl StdoutLock < ' _ > {
709+ #[ inline]
710+ fn inner ( & self ) -> RefMut < ' _ , LineWriter < StdoutRaw > > {
711+ #[ cold]
712+ fn init ( ) -> LineWriter < StdoutRaw > {
713+ LineWriter :: new ( stdout_raw ( ) )
714+ }
715+
716+ RefMut :: map ( self . inner . borrow_mut ( ) , |w| w. get_or_insert_with ( init) )
717+ }
718+ }
719+
715720#[ stable( feature = "rust1" , since = "1.0.0" ) ]
716721impl Write for StdoutLock < ' _ > {
717722 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
718- self . inner . borrow_mut ( ) . write ( buf)
723+ self . inner ( ) . write ( buf)
719724 }
720725 fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
721- self . inner . borrow_mut ( ) . write_vectored ( bufs)
726+ self . inner ( ) . write_vectored ( bufs)
722727 }
723728 #[ inline]
724729 fn is_write_vectored ( & self ) -> bool {
725- self . inner . borrow_mut ( ) . is_write_vectored ( )
730+ self . inner ( ) . is_write_vectored ( )
726731 }
727732 fn flush ( & mut self ) -> io:: Result < ( ) > {
728- self . inner . borrow_mut ( ) . flush ( )
733+ self . inner ( ) . flush ( )
729734 }
730735 fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
731- self . inner . borrow_mut ( ) . write_all ( buf)
736+ self . inner ( ) . write_all ( buf)
732737 }
733738 fn write_all_vectored ( & mut self , bufs : & mut [ IoSlice < ' _ > ] ) -> io:: Result < ( ) > {
734- self . inner . borrow_mut ( ) . write_all_vectored ( bufs)
739+ self . inner ( ) . write_all_vectored ( bufs)
735740 }
736741}
737742
@@ -761,7 +766,7 @@ impl fmt::Debug for StdoutLock<'_> {
761766/// standard library or via raw Windows API calls, will fail.
762767#[ stable( feature = "rust1" , since = "1.0.0" ) ]
763768pub struct Stderr {
764- inner : Pin < & ' static ReentrantMutex < RefCell < StderrRaw > > > ,
769+ inner : & ' static ReentrantMutex < RefCell < StderrRaw > > ,
765770}
766771
767772/// A locked reference to the [`Stderr`] handle.
@@ -834,16 +839,12 @@ pub struct StderrLock<'a> {
834839#[ stable( feature = "rust1" , since = "1.0.0" ) ]
835840pub fn stderr ( ) -> Stderr {
836841 // Note that unlike `stdout()` we don't use `at_exit` here to register a
837- // destructor. Stderr is not buffered , so there's no need to run a
842+ // destructor. Stderr is not buffered, so there's no need to run a
838843 // destructor for flushing the buffer
839- static INSTANCE : OnceLock < ReentrantMutex < RefCell < StderrRaw > > > = OnceLock :: new ( ) ;
844+ static INSTANCE : ReentrantMutex < RefCell < StderrRaw > > =
845+ ReentrantMutex :: new ( RefCell :: new ( stderr_raw ( ) ) ) ;
840846
841- Stderr {
842- inner : Pin :: static_ref ( & INSTANCE ) . get_or_init_pin (
843- || unsafe { ReentrantMutex :: new ( RefCell :: new ( stderr_raw ( ) ) ) } ,
844- |mutex| unsafe { mutex. init ( ) } ,
845- ) ,
846- }
847+ Stderr { inner : & INSTANCE }
847848}
848849
849850impl Stderr {
0 commit comments