Skip to content

Commit 72e9660

Browse files
committed
Remove io::LocalOutput and use Arc<Mutex<dyn>> for local streams.
1 parent cf9cf7c commit 72e9660

File tree

9 files changed

+51
-118
lines changed

9 files changed

+51
-118
lines changed

compiler/rustc_interface/src/util.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_span::symbol::{sym, Symbol};
2525
use smallvec::SmallVec;
2626
use std::env;
2727
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
28-
use std::io::{self, Write};
28+
use std::io;
2929
use std::lazy::SyncOnceCell;
3030
use std::mem;
3131
use std::ops::DerefMut;
@@ -106,21 +106,6 @@ fn get_stack_size() -> Option<usize> {
106106
env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE)
107107
}
108108

109-
struct Sink(Arc<Mutex<Vec<u8>>>);
110-
impl Write for Sink {
111-
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
112-
Write::write(&mut *self.0.lock().unwrap(), data)
113-
}
114-
fn flush(&mut self) -> io::Result<()> {
115-
Ok(())
116-
}
117-
}
118-
impl io::LocalOutput for Sink {
119-
fn clone_box(&self) -> Box<dyn io::LocalOutput> {
120-
Box::new(Self(self.0.clone()))
121-
}
122-
}
123-
124109
/// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
125110
/// for `'static` bounds.
126111
#[cfg(not(parallel_compiler))]
@@ -164,7 +149,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
164149
let main_handler = move || {
165150
rustc_span::with_session_globals(edition, || {
166151
if let Some(stderr) = stderr {
167-
io::set_panic(Some(box Sink(stderr.clone())));
152+
io::set_panic(Some(stderr.clone()));
168153
}
169154
f()
170155
})
@@ -204,7 +189,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
204189
let main_handler = move |thread: rayon::ThreadBuilder| {
205190
rustc_span::SESSION_GLOBALS.set(session_globals, || {
206191
if let Some(stderr) = stderr {
207-
io::set_panic(Some(box Sink(stderr.clone())));
192+
io::set_panic(Some(stderr.clone()));
208193
}
209194
thread.run()
210195
})

library/std/src/io/impls.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -209,20 +209,6 @@ impl<B: BufRead + ?Sized> BufRead for Box<B> {
209209
}
210210
}
211211

212-
// Used by panicking::default_hook
213-
#[cfg(test)]
214-
/// This impl is only used by printing logic, so any error returned is always
215-
/// of kind `Other`, and should be ignored.
216-
impl Write for dyn ::realstd::io::LocalOutput {
217-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
218-
(*self).write(buf).map_err(|_| ErrorKind::Other.into())
219-
}
220-
221-
fn flush(&mut self) -> io::Result<()> {
222-
(*self).flush().map_err(|_| ErrorKind::Other.into())
223-
}
224-
}
225-
226212
// =============================================================================
227213
// In-memory buffer implementations
228214

library/std/src/io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
277277
pub use self::stdio::{_eprint, _print};
278278
#[unstable(feature = "libstd_io_internals", issue = "42788")]
279279
#[doc(no_inline, hidden)]
280-
pub use self::stdio::{set_panic, set_print, LocalOutput};
280+
pub use self::stdio::{set_panic, set_print};
281281
#[stable(feature = "rust1", since = "1.0.0")]
282282
pub use self::util::{copy, empty, repeat, sink, Empty, Repeat, Sink};
283283

library/std/src/io/stdio.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,24 @@ use crate::fmt;
1010
use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
1111
use crate::lazy::SyncOnceCell;
1212
use crate::sync::atomic::{AtomicBool, Ordering};
13-
use crate::sync::{Mutex, MutexGuard};
13+
use crate::sync::{Arc, Mutex, MutexGuard};
1414
use crate::sys::stdio;
1515
use crate::sys_common;
1616
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
1717
use crate::thread::LocalKey;
1818

19+
type LocalStream = Arc<Mutex<dyn Write + Send>>;
20+
1921
thread_local! {
2022
/// Used by the test crate to capture the output of the print! and println! macros.
21-
static LOCAL_STDOUT: RefCell<Option<Box<dyn LocalOutput>>> = {
23+
static LOCAL_STDOUT: RefCell<Option<LocalStream>> = {
2224
RefCell::new(None)
2325
}
2426
}
2527

2628
thread_local! {
2729
/// Used by the test crate to capture the output of the eprint! and eprintln! macros, and panics.
28-
static LOCAL_STDERR: RefCell<Option<Box<dyn LocalOutput>>> = {
30+
static LOCAL_STDERR: RefCell<Option<LocalStream>> = {
2931
RefCell::new(None)
3032
}
3133
}
@@ -888,18 +890,6 @@ impl fmt::Debug for StderrLock<'_> {
888890
}
889891
}
890892

891-
/// A writer than can be cloned to new threads.
892-
#[unstable(
893-
feature = "set_stdio",
894-
reason = "this trait may disappear completely or be replaced \
895-
with a more general mechanism",
896-
issue = "none"
897-
)]
898-
#[doc(hidden)]
899-
pub trait LocalOutput: Write + Send {
900-
fn clone_box(&self) -> Box<dyn LocalOutput>;
901-
}
902-
903893
/// Resets the thread-local stderr handle to the specified writer
904894
///
905895
/// This will replace the current thread's stderr handle, returning the old
@@ -915,18 +905,17 @@ pub trait LocalOutput: Write + Send {
915905
issue = "none"
916906
)]
917907
#[doc(hidden)]
918-
pub fn set_panic(sink: Option<Box<dyn LocalOutput>>) -> Option<Box<dyn LocalOutput>> {
908+
pub fn set_panic(sink: Option<LocalStream>) -> Option<LocalStream> {
919909
use crate::mem;
920910
if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
921911
// LOCAL_STDERR is definitely None since LOCAL_STREAMS is false.
922912
return None;
923913
}
924-
let s = LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(
925-
|mut s| {
926-
let _ = s.flush();
914+
let s =
915+
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
916+
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
927917
Some(s)
928-
},
929-
);
918+
});
930919
LOCAL_STREAMS.store(true, Ordering::Relaxed);
931920
s
932921
}
@@ -946,35 +935,29 @@ pub fn set_panic(sink: Option<Box<dyn LocalOutput>>) -> Option<Box<dyn LocalOutp
946935
issue = "none"
947936
)]
948937
#[doc(hidden)]
949-
pub fn set_print(sink: Option<Box<dyn LocalOutput>>) -> Option<Box<dyn LocalOutput>> {
938+
pub fn set_print(sink: Option<LocalStream>) -> Option<LocalStream> {
950939
use crate::mem;
951940
if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
952941
// LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false.
953942
return None;
954943
}
955-
let s = LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(
956-
|mut s| {
957-
let _ = s.flush();
944+
let s =
945+
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
946+
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
958947
Some(s)
959-
},
960-
);
948+
});
961949
LOCAL_STREAMS.store(true, Ordering::Relaxed);
962950
s
963951
}
964952

965-
pub(crate) fn clone_io() -> (Option<Box<dyn LocalOutput>>, Option<Box<dyn LocalOutput>>) {
953+
pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
966954
// Don't waste time when LOCAL_{STDOUT,STDERR} are definitely None.
967955
if !LOCAL_STREAMS.load(Ordering::Relaxed) {
968956
return (None, None);
969957
}
970958

971959
LOCAL_STDOUT.with(|stdout| {
972-
LOCAL_STDERR.with(|stderr| {
973-
(
974-
stdout.borrow().as_ref().map(|o| o.clone_box()),
975-
stderr.borrow().as_ref().map(|o| o.clone_box()),
976-
)
977-
})
960+
LOCAL_STDERR.with(|stderr| (stdout.borrow().clone(), stderr.borrow().clone()))
978961
})
979962
}
980963

@@ -990,7 +973,7 @@ pub(crate) fn clone_io() -> (Option<Box<dyn LocalOutput>>, Option<Box<dyn LocalO
990973
/// However, if the actual I/O causes an error, this function does panic.
991974
fn print_to<T>(
992975
args: fmt::Arguments<'_>,
993-
local_s: &'static LocalKey<RefCell<Option<Box<dyn LocalOutput>>>>,
976+
local_s: &'static LocalKey<RefCell<Option<LocalStream>>>,
994977
global_s: fn() -> T,
995978
label: &str,
996979
) where
@@ -1005,8 +988,8 @@ fn print_to<T>(
1005988
// our printing recursively panics/prints, so the recursive
1006989
// panic/print goes to the global sink instead of our local sink.
1007990
let prev = s.borrow_mut().take();
1008-
if let Some(mut w) = prev {
1009-
let result = w.write_fmt(args);
991+
if let Some(w) = prev {
992+
let result = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
1010993
*s.borrow_mut() = Some(w);
1011994
return result;
1012995
}

library/std/src/panicking.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,29 @@ fn default_hook(info: &PanicInfo<'_>) {
218218
}
219219
};
220220

221-
if let Some(mut local) = set_panic(None) {
222-
// NB. In `cfg(test)` this uses the forwarding impl
223-
// for `dyn ::realstd::io::LocalOutput`.
224-
write(&mut local);
221+
if let Some(local) = set_panic(None) {
222+
let mut stream = local.lock().unwrap_or_else(|e| e.into_inner());
223+
224+
#[cfg(test)]
225+
{
226+
use crate::io;
227+
struct Wrapper<'a>(&'a mut (dyn ::realstd::io::Write + Send));
228+
impl io::Write for Wrapper<'_> {
229+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
230+
self.0.write(buf).map_err(|_| io::ErrorKind::Other.into())
231+
}
232+
fn flush(&mut self) -> io::Result<()> {
233+
self.0.flush().map_err(|_| io::ErrorKind::Other.into())
234+
}
235+
}
236+
write(&mut Wrapper(&mut *stream));
237+
}
238+
239+
#[cfg(not(test))]
240+
write(&mut *stream);
241+
242+
drop(stream);
243+
225244
set_panic(Some(local));
226245
} else if let Some(mut out) = panic_output() {
227246
write(&mut out);

library/test/src/bench.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
pub use std::hint::black_box;
33

44
use super::{
5-
event::CompletedTest, helpers::sink::Sink, options::BenchMode, test_result::TestResult,
6-
types::TestDesc, Sender,
5+
event::CompletedTest, options::BenchMode, test_result::TestResult, types::TestDesc, Sender,
76
};
87

98
use crate::stats;
@@ -186,10 +185,7 @@ where
186185

187186
let data = Arc::new(Mutex::new(Vec::new()));
188187
let oldio = if !nocapture {
189-
Some((
190-
io::set_print(Some(Sink::new_boxed(&data))),
191-
io::set_panic(Some(Sink::new_boxed(&data))),
192-
))
188+
Some((io::set_print(Some(data.clone())), io::set_panic(Some(data.clone()))))
193189
} else {
194190
None
195191
};

library/test/src/helpers/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ pub mod concurrency;
55
pub mod exit_code;
66
pub mod isatty;
77
pub mod metrics;
8-
pub mod sink;

library/test/src/helpers/sink.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

library/test/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ mod tests;
8989
use event::{CompletedTest, TestEvent};
9090
use helpers::concurrency::get_concurrency;
9191
use helpers::exit_code::get_exit_code;
92-
use helpers::sink::Sink;
9392
use options::{Concurrent, RunStrategy};
9493
use test_result::*;
9594
use time::TestExecTime;
@@ -532,10 +531,7 @@ fn run_test_in_process(
532531
let data = Arc::new(Mutex::new(Vec::new()));
533532

534533
let oldio = if !nocapture {
535-
Some((
536-
io::set_print(Some(Sink::new_boxed(&data))),
537-
io::set_panic(Some(Sink::new_boxed(&data))),
538-
))
534+
Some((io::set_print(Some(data.clone())), io::set_panic(Some(data.clone()))))
539535
} else {
540536
None
541537
};
@@ -556,7 +552,7 @@ fn run_test_in_process(
556552
Ok(()) => calc_result(&desc, Ok(()), &time_opts, &exec_time),
557553
Err(e) => calc_result(&desc, Err(e.as_ref()), &time_opts, &exec_time),
558554
};
559-
let stdout = data.lock().unwrap().to_vec();
555+
let stdout = data.lock().unwrap_or_else(|e| e.into_inner()).to_vec();
560556
let message = CompletedTest::new(desc, test_result, exec_time, stdout);
561557
monitor_ch.send(message).unwrap();
562558
}

0 commit comments

Comments
 (0)