diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-12-19 11:29:39 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-12-30 14:33:59 -0800 |
| commit | 9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7 (patch) | |
| tree | da18d5791e6841a1aa6a9469baca155d4ca9828d /src/libstd/io | |
| parent | d2368c3c11ddab9d812c4ddec2e44579326ad347 (diff) | |
| download | rust-9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7.tar.gz rust-9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7.zip | |
std: Re-enable at_exit()
The new semantics of this function are that the callbacks are run when the *main thread* exits, not when all threads have exited. This implies that other threads may still be running when the `at_exit` callbacks are invoked and users need to be prepared for this situation. Users in the standard library have been audited in accordance to these new rules as well. Closes #20012
Diffstat (limited to 'src/libstd/io')
| -rw-r--r-- | src/libstd/io/stdio.rs | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 6c8e4eea40f..fa04efce86e 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -26,29 +26,19 @@ //! ``` use self::StdSource::*; +use prelude::*; -use boxed::Box; use cell::RefCell; -use clone::Clone; use failure::LOCAL_STDERR; use fmt; -use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer, - standard_error, EndOfFile, LineBufferedWriter, BufferedReader}; -use kinds::{Sync, Send}; +use io::{IoResult, IoError, OtherIoError}; +use io::{standard_error, EndOfFile, LineBufferedWriter, BufferedReader}; use libc; use mem; -use option::Option; -use option::Option::{Some, None}; -use ops::{Deref, DerefMut, FnOnce}; -use result::Result::{Ok, Err}; use rt; -use slice::SliceExt; -use str::StrExt; -use string::String; use sys::{fs, tty}; -use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT}; +use sync::{Arc, Mutex, MutexGuard, StaticMutex, MUTEX_INIT}; use uint; -use vec::Vec; // And so begins the tale of acquiring a uv handle to a stdio stream on all // platforms in all situations. Our story begins by splitting the world into two @@ -215,14 +205,15 @@ impl Reader for StdinReader { pub fn stdin() -> StdinReader { // We're following the same strategy as kimundi's lazy_static library static mut STDIN: *const StdinReader = 0 as *const StdinReader; - static ONCE: Once = ONCE_INIT; + static LOCK: StaticMutex = MUTEX_INIT; unsafe { - ONCE.doit(|| { - // The default buffer capacity is 64k, but apparently windows doesn't like - // 64k reads on stdin. See #13304 for details, but the idea is that on - // windows we use a slightly smaller buffer that's been seen to be - // acceptable. + let _g = LOCK.lock(); + if STDIN as uint == 0 { + // The default buffer capacity is 64k, but apparently windows + // doesn't like 64k reads on stdin. See #13304 for details, but the + // idea is that on windows we use a slightly smaller buffer that's + // been seen to be acceptable. let stdin = if cfg!(windows) { BufferedReader::with_capacity(8 * 1024, stdin_raw()) } else { @@ -235,11 +226,15 @@ pub fn stdin() -> StdinReader { // Make sure to free it at exit rt::at_exit(|| { - mem::transmute::<_, Box<StdinReader>>(STDIN); - STDIN = 0 as *const _; + let g = LOCK.lock(); + let stdin = STDIN; + STDIN = 1 as *const _; + drop(g); + mem::transmute::<_, Box<StdinReader>>(stdin); }); - }); - + } else if STDIN as uint == 1 { + panic!("accessing stdin after the main thread has exited") + } (*STDIN).clone() } } |
