aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/io/stdio.rs
diff options
context:
space:
mode:
authorFenrir <[email protected]>2018-08-19 17:48:00 -0600
committerFenrir <[email protected]>2018-08-19 17:56:18 -0600
commit5d28bfcfd6086c3328837de9695099ea39048d0d (patch)
treea514fde042ff2a504a03305bfe0894ff8cd8d47e /ctr-std/src/io/stdio.rs
parentUpdate for latest nightly 2018-06-09 (#70) (diff)
downloadctru-rs-5d28bfcfd6086c3328837de9695099ea39048d0d.tar.xz
ctru-rs-5d28bfcfd6086c3328837de9695099ea39048d0d.zip
Update for nightly-2018-08-18
Diffstat (limited to 'ctr-std/src/io/stdio.rs')
-rw-r--r--ctr-std/src/io/stdio.rs40
1 files changed, 33 insertions, 7 deletions
diff --git a/ctr-std/src/io/stdio.rs b/ctr-std/src/io/stdio.rs
index 2472bed..1f256f5 100644
--- a/ctr-std/src/io/stdio.rs
+++ b/ctr-std/src/io/stdio.rs
@@ -21,7 +21,7 @@ use thread::LocalKey;
/// Stdout used by print! and println! macros
thread_local! {
- static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
+ static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
RefCell::new(None)
}
}
@@ -197,12 +197,13 @@ pub struct StdinLock<'a> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdin() -> Stdin {
- static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = Lazy::new(stdin_init);
+ static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = unsafe { Lazy::new(stdin_init) };
return Stdin {
inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
};
fn stdin_init() -> Arc<Mutex<BufReader<Maybe<StdinRaw>>>> {
+ // This must not reentrantly access `INSTANCE`
let stdin = match stdin_raw() {
Ok(stdin) => Maybe::Real(stdin),
_ => Maybe::Fake
@@ -396,12 +397,13 @@ pub struct StdoutLock<'a> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdout() -> Stdout {
static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>
- = Lazy::new(stdout_init);
+ = unsafe { Lazy::new(stdout_init) };
return Stdout {
inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
};
fn stdout_init() -> Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> {
+ // This must not reentrantly access `INSTANCE`
let stdout = match stdout_raw() {
Ok(stdout) => Maybe::Real(stdout),
_ => Maybe::Fake,
@@ -531,12 +533,14 @@ pub struct StderrLock<'a> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stderr() -> Stderr {
- static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = Lazy::new(stderr_init);
+ static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> =
+ unsafe { Lazy::new(stderr_init) };
return Stderr {
inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
};
fn stderr_init() -> Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> {
+ // This must not reentrantly access `INSTANCE`
let stderr = match stderr_raw() {
Ok(stderr) => Maybe::Real(stderr),
_ => Maybe::Fake,
@@ -624,7 +628,7 @@ impl<'a> fmt::Debug for StderrLock<'a> {
with a more general mechanism",
issue = "0")]
#[doc(hidden)]
-pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
use panicking::LOCAL_STDERR;
use mem;
LOCAL_STDERR.with(move |slot| {
@@ -648,7 +652,7 @@ pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
with a more general mechanism",
issue = "0")]
#[doc(hidden)]
-pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
use mem;
LOCAL_STDOUT.with(move |slot| {
mem::replace(&mut *slot.borrow_mut(), sink)
@@ -670,7 +674,7 @@ pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
/// However, if the actual I/O causes an error, this function does panic.
fn print_to<T>(
args: fmt::Arguments,
- local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>,
+ local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>,
global_s: fn() -> T,
label: &str,
)
@@ -712,10 +716,32 @@ pub fn _eprint(args: fmt::Arguments) {
#[cfg(test)]
mod tests {
+ use panic::{UnwindSafe, RefUnwindSafe};
use thread;
use super::*;
#[test]
+ fn stdout_unwind_safe() {
+ assert_unwind_safe::<Stdout>();
+ }
+ #[test]
+ fn stdoutlock_unwind_safe() {
+ assert_unwind_safe::<StdoutLock>();
+ assert_unwind_safe::<StdoutLock<'static>>();
+ }
+ #[test]
+ fn stderr_unwind_safe() {
+ assert_unwind_safe::<Stderr>();
+ }
+ #[test]
+ fn stderrlock_unwind_safe() {
+ assert_unwind_safe::<StderrLock>();
+ assert_unwind_safe::<StderrLock<'static>>();
+ }
+
+ fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
+
+ #[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn panic_doesnt_poison() {
thread::spawn(|| {