Skip to content

Commit 94d71f8

Browse files
committed
std: Implement stdio for std::io
This is an implementation of RFC 899 and adds stdio functionality to the new `std::io` module. Details of the API can be found on the RFC, but from a high level: * `io::{stdin, stdout, stderr}` constructors are now available. There are also `*_raw` variants for unbuffered and unlocked access. * All handles are globally shared (excluding raw variants). * The stderr handle is no longer buffered. * All handles can be explicitly locked (excluding the raw variants). The `print!` and `println!` machinery has not yet been hooked up to these streams just yet. The `std::fmt::output` module has also not yet been implemented as part of this commit.
1 parent 8a69110 commit 94d71f8

20 files changed

+732
-108
lines changed

src/liballoc/arc.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,11 @@ impl<T> Arc<T> {
201201
impl<T> Arc<T> {
202202
#[inline]
203203
fn inner(&self) -> &ArcInner<T> {
204-
// This unsafety is ok because while this arc is alive we're guaranteed that the inner
205-
// pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
206-
// because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
207-
// to these contents.
204+
// This unsafety is ok because while this arc is alive we're guaranteed
205+
// that the inner pointer is valid. Furthermore, we know that the
206+
// `ArcInner` structure itself is `Sync` because the inner data is
207+
// `Sync` as well, so we're ok loaning out an immutable pointer to these
208+
// contents.
208209
unsafe { &**self._ptr }
209210
}
210211
}
@@ -236,13 +237,15 @@ impl<T> Clone for Arc<T> {
236237
/// ```
237238
#[inline]
238239
fn clone(&self) -> Arc<T> {
239-
// Using a relaxed ordering is alright here, as knowledge of the original reference
240-
// prevents other threads from erroneously deleting the object.
240+
// Using a relaxed ordering is alright here, as knowledge of the
241+
// original reference prevents other threads from erroneously deleting
242+
// the object.
241243
//
242-
// As explained in the [Boost documentation][1], Increasing the reference counter can
243-
// always be done with memory_order_relaxed: New references to an object can only be formed
244-
// from an existing reference, and passing an existing reference from one thread to another
245-
// must already provide any required synchronization.
244+
// As explained in the [Boost documentation][1], Increasing the
245+
// reference counter can always be done with memory_order_relaxed: New
246+
// references to an object can only be formed from an existing
247+
// reference, and passing an existing reference from one thread to
248+
// another must already provide any required synchronization.
246249
//
247250
// [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
248251
self.inner().strong.fetch_add(1, Relaxed);

src/libstd/io/lazy.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use prelude::v1::*;
12+
13+
use boxed;
14+
use cell::UnsafeCell;
15+
use rt;
16+
use sync::{StaticMutex, Arc};
17+
18+
pub struct Lazy<T> {
19+
pub lock: StaticMutex,
20+
pub ptr: UnsafeCell<*mut Arc<T>>,
21+
pub init: fn() -> Arc<T>,
22+
}
23+
24+
unsafe impl<T> Sync for Lazy<T> {}
25+
26+
macro_rules! lazy_init {
27+
($init:expr) => (::io::lazy::Lazy {
28+
lock: ::sync::MUTEX_INIT,
29+
ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
30+
init: $init,
31+
})
32+
}
33+
34+
impl<T: Send + Sync + 'static> Lazy<T> {
35+
pub fn get(&'static self) -> Option<Arc<T>> {
36+
let _g = self.lock.lock();
37+
unsafe {
38+
let mut ptr = *self.ptr.get();
39+
if ptr.is_null() {
40+
ptr = boxed::into_raw(self.init());
41+
*self.ptr.get() = ptr;
42+
} else if ptr as usize == 1 {
43+
return None
44+
}
45+
Some((*ptr).clone())
46+
}
47+
}
48+
49+
fn init(&'static self) -> Box<Arc<T>> {
50+
rt::at_exit(move || unsafe {
51+
let g = self.lock.lock();
52+
let ptr = *self.ptr.get();
53+
*self.ptr.get() = 1 as *mut _;
54+
drop(g);
55+
drop(Box::from_raw(ptr))
56+
});
57+
Box::new((self.init)())
58+
}
59+
}

src/libstd/io/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,18 @@ pub use self::buffered::IntoInnerError;
3939
pub use self::cursor::Cursor;
4040
pub use self::error::{Result, Error, ErrorKind};
4141
pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
42+
pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
43+
pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
44+
45+
#[macro_use] mod lazy;
4246

4347
pub mod prelude;
4448
mod buffered;
4549
mod cursor;
4650
mod error;
4751
mod impls;
4852
mod util;
53+
mod stdio;
4954

5055
const DEFAULT_BUF_SIZE: usize = 64 * 1024;
5156

0 commit comments

Comments
 (0)