@@ -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