@@ -8,7 +8,6 @@ use crate::io::prelude::*;
8
8
use crate :: cell:: { Cell , RefCell } ;
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
@@ -670,7 +663,7 @@ impl Write for Stdout {
670
663
}
671
664
#[ inline]
672
665
fn is_write_vectored ( & self ) -> bool {
673
- io :: Write :: is_write_vectored ( & & * self )
666
+ stdout_raw ( ) . is_write_vectored ( )
674
667
}
675
668
fn flush ( & mut self ) -> io:: Result < ( ) > {
676
669
( & * self ) . flush ( )
@@ -696,7 +689,7 @@ impl Write for &Stdout {
696
689
}
697
690
#[ inline]
698
691
fn is_write_vectored ( & self ) -> bool {
699
- self . lock ( ) . is_write_vectored ( )
692
+ stdout_raw ( ) . is_write_vectored ( )
700
693
}
701
694
fn flush ( & mut self ) -> io:: Result < ( ) > {
702
695
self . lock ( ) . flush ( )
@@ -712,26 +705,37 @@ impl Write for &Stdout {
712
705
}
713
706
}
714
707
708
+ impl StdoutLock < ' _ > {
709
+ #[ inline]
710
+ fn with_inner < F , R > ( & mut self , f : F ) -> R
711
+ where
712
+ F : FnOnce ( & mut LineWriter < StdoutRaw > ) -> R ,
713
+ {
714
+ let mut inner = self . inner . borrow_mut ( ) ;
715
+ f ( inner. get_or_insert_with ( || LineWriter :: new ( stdout_raw ( ) ) ) )
716
+ }
717
+ }
718
+
715
719
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
716
720
impl Write for StdoutLock < ' _ > {
717
721
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
718
- self . inner . borrow_mut ( ) . write ( buf)
722
+ self . with_inner ( |stdout| stdout . write ( buf) )
719
723
}
720
724
fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
721
- self . inner . borrow_mut ( ) . write_vectored ( bufs)
725
+ self . with_inner ( |stdout| stdout . write_vectored ( bufs) )
722
726
}
723
727
#[ inline]
724
728
fn is_write_vectored ( & self ) -> bool {
725
- self . inner . borrow_mut ( ) . is_write_vectored ( )
729
+ stdout_raw ( ) . is_write_vectored ( )
726
730
}
727
731
fn flush ( & mut self ) -> io:: Result < ( ) > {
728
- self . inner . borrow_mut ( ) . flush ( )
732
+ self . with_inner ( |stdout| stdout . flush ( ) )
729
733
}
730
734
fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
731
- self . inner . borrow_mut ( ) . write_all ( buf)
735
+ self . with_inner ( |stdout| stdout . write_all ( buf) )
732
736
}
733
737
fn write_all_vectored ( & mut self , bufs : & mut [ IoSlice < ' _ > ] ) -> io:: Result < ( ) > {
734
- self . inner . borrow_mut ( ) . write_all_vectored ( bufs)
738
+ self . with_inner ( |stdout| stdout . write_all_vectored ( bufs) )
735
739
}
736
740
}
737
741
@@ -761,7 +765,7 @@ impl fmt::Debug for StdoutLock<'_> {
761
765
/// standard library or via raw Windows API calls, will fail.
762
766
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
763
767
pub struct Stderr {
764
- inner : Pin < & ' static ReentrantMutex < RefCell < StderrRaw > > > ,
768
+ inner : & ' static ReentrantMutex < RefCell < StderrRaw > > ,
765
769
}
766
770
767
771
/// A locked reference to the [`Stderr`] handle.
@@ -834,16 +838,12 @@ pub struct StderrLock<'a> {
834
838
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
835
839
pub fn stderr ( ) -> Stderr {
836
840
// 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
841
+ // destructor. Stderr is not buffered, so there's no need to run a
838
842
// destructor for flushing the buffer
839
- static INSTANCE : OnceLock < ReentrantMutex < RefCell < StderrRaw > > > = OnceLock :: new ( ) ;
843
+ static INSTANCE : ReentrantMutex < RefCell < StderrRaw > > =
844
+ ReentrantMutex :: new ( RefCell :: new ( stderr_raw ( ) ) ) ;
840
845
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
- }
846
+ Stderr { inner : & INSTANCE }
847
847
}
848
848
849
849
impl Stderr {
0 commit comments