@@ -5,10 +5,9 @@ mod tests;
5
5
6
6
use crate :: io:: prelude:: * ;
7
7
8
- use crate :: cell:: { Cell , RefCell } ;
8
+ use crate :: cell:: { Cell , RefCell , RefMut } ;
9
9
use crate :: fmt;
10
10
use crate :: io:: { self , BufReader , IoSlice , IoSliceMut , LineWriter , Lines } ;
11
- use crate :: pin:: Pin ;
12
11
use crate :: sync:: atomic:: { AtomicBool , Ordering } ;
13
12
use crate :: sync:: { Arc , Mutex , MutexGuard , OnceLock } ;
14
13
use crate :: sys:: stdio;
@@ -526,7 +525,7 @@ pub struct Stdout {
526
525
// FIXME: this should be LineWriter or BufWriter depending on the state of
527
526
// stdout (tty or not). Note that if this is not line buffered it
528
527
// 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 > > > > ,
530
529
}
531
530
532
531
/// A locked reference to the [`Stdout`] handle.
@@ -548,10 +547,11 @@ pub struct Stdout {
548
547
#[ must_use = "if unused stdout will immediately unlock" ]
549
548
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
550
549
pub struct StdoutLock < ' a > {
551
- inner : ReentrantMutexGuard < ' a , RefCell < LineWriter < StdoutRaw > > > ,
550
+ inner : ReentrantMutexGuard < ' a , RefCell < Option < LineWriter < StdoutRaw > > > > ,
552
551
}
553
552
554
- static STDOUT : OnceLock < ReentrantMutex < RefCell < LineWriter < StdoutRaw > > > > = OnceLock :: new ( ) ;
553
+ static STDOUT : ReentrantMutex < RefCell < Option < LineWriter < StdoutRaw > > > > =
554
+ ReentrantMutex :: new ( RefCell :: new ( None ) ) ;
555
555
556
556
/// Constructs a new handle to the standard output of the current process.
557
557
///
@@ -602,25 +602,18 @@ static STDOUT: OnceLock<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = OnceLo
602
602
#[ must_use]
603
603
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
604
604
pub 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 }
611
606
}
612
607
613
608
pub 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 ( ) ) ) ;
624
617
}
625
618
}
626
619
@@ -712,26 +705,38 @@ impl Write for &Stdout {
712
705
}
713
706
}
714
707
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
+
715
720
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
716
721
impl Write for StdoutLock < ' _ > {
717
722
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
718
- self . inner . borrow_mut ( ) . write ( buf)
723
+ self . inner ( ) . write ( buf)
719
724
}
720
725
fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
721
- self . inner . borrow_mut ( ) . write_vectored ( bufs)
726
+ self . inner ( ) . write_vectored ( bufs)
722
727
}
723
728
#[ inline]
724
729
fn is_write_vectored ( & self ) -> bool {
725
- self . inner . borrow_mut ( ) . is_write_vectored ( )
730
+ self . inner ( ) . is_write_vectored ( )
726
731
}
727
732
fn flush ( & mut self ) -> io:: Result < ( ) > {
728
- self . inner . borrow_mut ( ) . flush ( )
733
+ self . inner ( ) . flush ( )
729
734
}
730
735
fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
731
- self . inner . borrow_mut ( ) . write_all ( buf)
736
+ self . inner ( ) . write_all ( buf)
732
737
}
733
738
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)
735
740
}
736
741
}
737
742
@@ -761,7 +766,7 @@ impl fmt::Debug for StdoutLock<'_> {
761
766
/// standard library or via raw Windows API calls, will fail.
762
767
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
763
768
pub struct Stderr {
764
- inner : Pin < & ' static ReentrantMutex < RefCell < StderrRaw > > > ,
769
+ inner : & ' static ReentrantMutex < RefCell < StderrRaw > > ,
765
770
}
766
771
767
772
/// A locked reference to the [`Stderr`] handle.
@@ -834,16 +839,12 @@ pub struct StderrLock<'a> {
834
839
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
835
840
pub fn stderr ( ) -> Stderr {
836
841
// 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
838
843
// 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 ( ) ) ) ;
840
846
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 }
847
848
}
848
849
849
850
impl Stderr {
0 commit comments