diff --git a/AUTHORS.txt b/AUTHORS.txt index 83d8d9ef0c8b5..0f20e510adcd8 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -518,6 +518,7 @@ Luke Francl Luke Metz Luke Steensen Luqman Aden +Łukasz Niemier Magnus Auvinen Mahmut Bulut Makoto Nakashima @@ -997,5 +998,4 @@ xales zofrex zslayton zzmp -Łukasz Niemier 克雷 diff --git a/configure b/configure index 9aebfe07967d9..f0cba4b0c6a6d 100755 --- a/configure +++ b/configure @@ -844,7 +844,7 @@ then CFG_OSX_GCC_VERSION=$("$CFG_GCC" --version 2>&1 | grep "Apple LLVM version") if [ $? -eq 0 ] then - step_msg "on OS X 10.9, forcing use of clang" + step_msg "on OS X >=10.9, forcing use of clang" CFG_ENABLE_CLANG=1 else if [ $("$CFG_GCC" --version 2>&1 | grep -c ' 4\.[0-6]') -ne 0 ]; then diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md index 6b58f7dfde817..57479a21e47a8 100644 --- a/src/doc/trpl/guessing-game.md +++ b/src/doc/trpl/guessing-game.md @@ -358,11 +358,10 @@ rand="0.3.0" The `[dependencies]` section of `Cargo.toml` is like the `[package]` section: everything that follows it is part of it, until the next section starts. Cargo uses the dependencies section to know what dependencies on external -crates you have, and what versions you require. In this case, we’ve used `*`, -which means that we’ll use the latest version of `rand`. Cargo understands -[Semantic Versioning][semver], which is a standard for writing version -numbers. If we wanted a specific version or range of versions, we could be -more specific here. [Cargo’s documentation][cargodoc] contains more details. +crates you have, and what versions you require. In this case, we’ve used version `0.3.0`. +Cargo understands [Semantic Versioning][semver], which is a standard for writing version +numbers. If we wanted to use the latest version we could use `*` or we could use a range +of versions. [Cargo’s documentation][cargodoc] contains more details. [semver]: http://semver.org [cargodoc]: http://doc.crates.io/crates-io.html @@ -410,7 +409,7 @@ $ cargo build Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game) ``` -So, we told Cargo we wanted any version of `rand`, and so it fetched the latest +So, we told Cargo we wanted any `0.3.x` version of `rand`, and so it fetched the latest version at the time this was written, `v0.3.8`. But what happens when next week, version `v0.3.9` comes out, with an important bugfix? While getting bugfixes is important, what if `0.3.9` contains a regression that breaks our diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 981286c82d798..86164a08a430f 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -116,7 +116,7 @@ fn main() { } ``` -[struct]: structs.html +[structs]: structs.html As you can see, `struct`s can also have lifetimes. In a similar way to functions, diff --git a/src/doc/trpl/mutability.md b/src/doc/trpl/mutability.md index 816bfb1797061..435407a8a967d 100644 --- a/src/doc/trpl/mutability.md +++ b/src/doc/trpl/mutability.md @@ -85,7 +85,7 @@ safety, and the mechanism by which Rust guarantees it, the > You may have one or the other of these two kinds of borrows, but not both at > the same time: > -> * 0 to N references (`&T`) to a resource. +> * one or more references (`&T`) to a resource. > * exactly one mutable reference (`&mut T`) [ownership]: ownership.html diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 3003156f875aa..fba5226ca2ed9 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -3,7 +3,7 @@ This guide is one of three presenting Rust’s ownership system. This is one of Rust’s most unique and compelling features, with which Rust developers should become quite acquainted. Ownership is how Rust achieves its largest goal, -memory safety. The there are a few distinct concepts, each with its own +memory safety. There are a few distinct concepts, each with its own chapter: * ownership, which you’re reading now. @@ -59,6 +59,7 @@ deterministically, at the end of the scope. [vect]: ../std/vec/struct.Vec.html [heap]: the-stack-and-the-heap.html +[bindings]: variable-bindings.html # Move semantics @@ -122,7 +123,7 @@ let v2 = v; The first line creates some data for the vector on the [stack][sh], `v`. The vector’s data, however, is stored on the [heap][sh], and so it contains a -pointer to that data. When we move `v` to `v2`, it creates a copy of that data, +pointer to that data. When we move `v` to `v2`, it creates a copy of that pointer, for `v2`. Which would mean two pointers to the contents of the vector on the heap. That would be a problem: it would violate Rust’s safety guarantees by introducing a data race. Therefore, Rust forbids using `v` after we’ve done the diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md index 21feff73342ce..8bb3f94760bc9 100644 --- a/src/doc/trpl/references-and-borrowing.md +++ b/src/doc/trpl/references-and-borrowing.md @@ -3,7 +3,7 @@ This guide is one of three presenting Rust’s ownership system. This is one of Rust’s most unique and compelling features, with which Rust developers should become quite acquainted. Ownership is how Rust achieves its largest goal, -memory safety. The there are a few distinct concepts, each with its own +memory safety. There are a few distinct concepts, each with its own chapter: * [ownership][ownership], ownership, the key concept diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index ea5d2ed711fed..51ee4bf0cdc28 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -192,7 +192,7 @@ Here’s the error: ```text error: type `std::fs::File` does not implement any method in scope named `write` -let result = f.write(b”whatever”); +let result = f.write(b"whatever"); ^~~~~~~~~~~~~~~~~~ ``` diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index a787d34f9145a..de962b51e0590 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -137,7 +137,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// assert!(a.iter().last().unwrap() == &5); + /// assert_eq!(a.iter().last().unwrap(), &5); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -155,8 +155,8 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); - /// assert!(it.nth(2).unwrap() == &3); - /// assert!(it.nth(2) == None); + /// assert_eq!(it.nth(2).unwrap(), &3); + /// assert_eq!(it.nth(2), None); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -545,8 +545,8 @@ pub trait Iterator { /// let mut it = 0..10; /// // sum the first five values /// let partial_sum = it.by_ref().take(5).fold(0, |a, b| a + b); - /// assert!(partial_sum == 10); - /// assert!(it.next() == Some(5)); + /// assert_eq!(partial_sum, 10); + /// assert_eq!(it.next(), Some(5)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self where Self: Sized { self } @@ -608,7 +608,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// assert!(a.iter().fold(0, |acc, &item| acc + item) == 15); + /// assert_eq!(a.iter().fold(0, |acc, &item| acc + item), 15); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -773,7 +773,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// assert!(a.iter().max().unwrap() == &5); + /// assert_eq!(a.iter().max().unwrap(), &5); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -796,7 +796,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// assert!(a.iter().min().unwrap() == &1); + /// assert_eq!(a.iter().min().unwrap(), &1); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -834,13 +834,13 @@ pub trait Iterator { /// assert_eq!(a.iter().min_max(), NoElements); /// /// let a = [1]; - /// assert!(a.iter().min_max() == OneElement(&1)); + /// assert_eq!(a.iter().min_max(), OneElement(&1)); /// /// let a = [1, 2, 3, 4, 5]; - /// assert!(a.iter().min_max() == MinMax(&1, &5)); + /// assert_eq!(a.iter().min_max(), MinMax(&1, &5)); /// /// let a = [1, 1, 1, 1]; - /// assert!(a.iter().min_max() == MinMax(&1, &1)); + /// assert_eq!(a.iter().min_max(), MinMax(&1, &1)); /// ``` #[unstable(feature = "core", reason = "return type may change")] fn min_max(mut self) -> MinMaxResult where Self: Sized, Self::Item: Ord @@ -1058,7 +1058,7 @@ pub trait Iterator { /// /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter().cloned(); - /// assert!(it.sum::() == 15); + /// assert_eq!(it.sum::(), 15); /// ``` #[unstable(feature="core")] fn sum::Item>(self) -> S where @@ -1078,9 +1078,9 @@ pub trait Iterator { /// fn factorial(n: u32) -> u32 { /// (1..).take_while(|&i| i <= n).product() /// } - /// assert!(factorial(0) == 1); - /// assert!(factorial(1) == 1); - /// assert!(factorial(5) == 120); + /// assert_eq!(factorial(0), 1); + /// assert_eq!(factorial(1), 1); + /// assert_eq!(factorial(5), 120); /// ``` #[unstable(feature="core")] fn product::Item>(self) -> P where diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 04839b12ac895..1bd0b3638c683 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -313,7 +313,7 @@ macro_rules! impls{ /// mismatches by enforcing types in the method implementations: /// /// ``` -/// # trait ResType { fn foo(&self); }; +/// # trait ResType { fn foo(&self); } /// # struct ParamType; /// # mod foreign_lib { /// # pub fn new(_: usize) -> *mut () { 42 as *mut () } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 4cbc3b4725d3b..55934da00a37c 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -12,7 +12,8 @@ #![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "libc"] #![crate_type = "rlib"] -#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))] +#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc", + reason = "use `libc` from crates.io"))] #![cfg_attr(not(feature = "cargo-build"), feature(staged_api, core, no_std))] #![cfg_attr(not(feature = "cargo-build"), staged_api)] #![cfg_attr(not(feature = "cargo-build"), no_std)] @@ -3624,6 +3625,30 @@ pub mod consts { pub const IPV6_DROP_MEMBERSHIP: c_int = 21; pub const TCP_NODELAY: c_int = 1; + pub const TCP_MAXSEG: c_int = 2; + pub const TCP_CORK: c_int = 3; + pub const TCP_KEEPIDLE: c_int = 4; + pub const TCP_KEEPINTVL: c_int = 5; + pub const TCP_KEEPCNT: c_int = 6; + pub const TCP_SYNCNT: c_int = 7; + pub const TCP_LINGER2: c_int = 8; + pub const TCP_DEFER_ACCEPT: c_int = 9; + pub const TCP_WINDOW_CLAMP: c_int = 10; + pub const TCP_INFO: c_int = 11; + pub const TCP_QUICKACK: c_int = 12; + pub const TCP_CONGESTION: c_int = 13; + pub const TCP_MD5SIG: c_int = 14; + pub const TCP_COOKIE_TRANSACTIONS: c_int = 15; + pub const TCP_THIN_LINEAR_TIMEOUTS: c_int = 16; + pub const TCP_THIN_DUPACK: c_int = 17; + pub const TCP_USER_TIMEOUT: c_int = 18; + pub const TCP_REPAIR: c_int = 19; + pub const TCP_REPAIR_QUEUE: c_int = 20; + pub const TCP_QUEUE_SEQ: c_int = 21; + pub const TCP_REPAIR_OPTIONS: c_int = 22; + pub const TCP_FASTOPEN: c_int = 23; + pub const TCP_TIMESTAMP: c_int = 24; + pub const SOL_SOCKET: c_int = 65535; pub const SO_DEBUG: c_int = 0x0001; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 53ea28f0c11d3..1359894b4dd72 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -26,7 +26,8 @@ html_playground_url = "http://play.rust-lang.org/")] #![no_std] #![staged_api] -#![unstable(feature = "rand")] +#![unstable(feature = "rand", + reason = "use `rand` from crates.io")] #![feature(core)] #![feature(no_std)] #![feature(staged_api)] diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 154d824e67846..f00f0eea1f48d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -12,6 +12,28 @@ register_long_diagnostics! { +E0046: r##" +When trying to make some type implement a trait `Foo`, you must, at minimum, +provide implementations for all of `Foo`'s required methods (meaning the +methods that do not have default implementations), as well as any required +trait items like associated types or constants. +"##, + +E0054: r##" +It is not allowed to cast to a bool. If you are trying to cast a numeric type +to a bool, you can compare it with zero instead: + +``` +let x = 5; + +// Ok +let x_is_nonzero = x != 0; + +// Not allowed, won't compile +let x_is_nonzero = x as bool; +``` +"##, + E0081: r##" Enum discriminants are used to differentiate enum variants stored in memory. This error indicates that the same value was used for two or more variants, @@ -106,11 +128,9 @@ register_diagnostics! { E0040, // explicit use of destructor method E0044, E0045, - E0046, E0049, E0050, E0053, - E0054, E0055, E0057, E0059, diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 5a05c61e064df..fc5405ea7f69e 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -23,7 +23,7 @@ use fmt; use ffi::OsString; use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write}; use path::{Path, PathBuf}; -use sys::fs2 as fs_imp; +use sys::fs as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index bf444ce671dfc..bff9774bcd04a 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -15,7 +15,7 @@ use prelude::v1::*; use io::{self, Error, ErrorKind}; -use sys_common::net2 as net_imp; +use sys_common::net as net_imp; pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index c0d880877b511..db2cdb7319880 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -17,7 +17,7 @@ use io::prelude::*; use fmt; use io; use net::{ToSocketAddrs, SocketAddr, Shutdown}; -use sys_common::net2 as net_imp; +use sys_common::net as net_imp; use sys_common::{AsInner, FromInner}; /// A structure which represents a TCP stream between a local socket and a diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 4360f62c1bf0f..67c7096904d6f 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -16,7 +16,7 @@ use prelude::v1::*; use fmt; use io::{self, Error, ErrorKind}; use net::{ToSocketAddrs, SocketAddr, IpAddr}; -use sys_common::net2 as net_imp; +use sys_common::net as net_imp; use sys_common::{AsInner, FromInner}; /// A User Datagram Protocol socket. diff --git a/src/libstd/os/android/mod.rs b/src/libstd/os/android/mod.rs index 346a903c4d9a9..a94abba5d12bf 100644 --- a/src/libstd/os/android/mod.rs +++ b/src/libstd/os/android/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/bitrig/mod.rs b/src/libstd/os/bitrig/mod.rs index 01ea542b3b713..1fe5fdd4e146c 100644 --- a/src/libstd/os/bitrig/mod.rs +++ b/src/libstd/os/bitrig/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/dragonfly/mod.rs b/src/libstd/os/dragonfly/mod.rs index 677f8b706cdbd..d5c7c58173333 100644 --- a/src/libstd/os/dragonfly/mod.rs +++ b/src/libstd/os/dragonfly/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/freebsd/mod.rs b/src/libstd/os/freebsd/mod.rs index 73b6fd211371c..28c9f8321f8a9 100644 --- a/src/libstd/os/freebsd/mod.rs +++ b/src/libstd/os/freebsd/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/ios/mod.rs b/src/libstd/os/ios/mod.rs index d471cf12fe63e..dd2878c6e383c 100644 --- a/src/libstd/os/ios/mod.rs +++ b/src/libstd/os/ios/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/linux/mod.rs b/src/libstd/os/linux/mod.rs index 43376a1baeb92..d2f9bcc3bcf9e 100644 --- a/src/libstd/os/linux/mod.rs +++ b/src/libstd/os/linux/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs index adce5f22ebc10..9589f4cf099b2 100644 --- a/src/libstd/os/linux/raw.rs +++ b/src/libstd/os/linux/raw.rs @@ -60,8 +60,8 @@ mod arch { #[cfg(any(target_arch = "mips", target_arch = "mipsel"))] mod arch { - use super::{dev_t, mode_t}; - use os::raw::c_long; + use super::mode_t; + use os::raw::{c_long, c_ulong}; use os::unix::raw::{gid_t, uid_t}; pub type blkcnt_t = i32; diff --git a/src/libstd/os/macos/mod.rs b/src/libstd/os/macos/mod.rs index bc5ff5b25d2fa..6c96909f382e8 100644 --- a/src/libstd/os/macos/mod.rs +++ b/src/libstd/os/macos/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/nacl/mod.rs b/src/libstd/os/nacl/mod.rs index 6baed03951467..413bb72f6e1c3 100644 --- a/src/libstd/os/nacl/mod.rs +++ b/src/libstd/os/nacl/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/os/openbsd/mod.rs b/src/libstd/os/openbsd/mod.rs index 1b1a10055902b..5654a7a022963 100644 --- a/src/libstd/os/openbsd/mod.rs +++ b/src/libstd/os/openbsd/mod.rs @@ -15,5 +15,5 @@ pub mod raw; pub mod fs { - pub use sys::fs2::MetadataExt; + pub use sys::fs::MetadataExt; } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 8f8699f4b9fea..61398e16ba036 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -21,11 +21,11 @@ use fmt; use io::{self, Error, ErrorKind}; use path; use sync::mpsc::{channel, Receiver}; -use sys::pipe2::{self, AnonPipe}; -use sys::process2::Command as CommandImp; -use sys::process2::Process as ProcessImp; -use sys::process2::ExitStatus as ExitStatusImp; -use sys::process2::Stdio as StdioImp2; +use sys::pipe::{self, AnonPipe}; +use sys::process::Command as CommandImp; +use sys::process::Process as ProcessImp; +use sys::process::ExitStatus as ExitStatusImp; +use sys::process::Stdio as StdioImp2; use sys_common::{AsInner, AsInnerMut}; use thread; @@ -334,7 +334,7 @@ fn setup_io(io: &StdioImp, readable: bool) Null => (StdioImp2::None, None), Inherit => (StdioImp2::Inherit, None), Piped => { - let (reader, writer) = try!(pipe2::anon_pipe()); + let (reader, writer) = try!(pipe::anon_pipe()); if readable { (StdioImp2::Piped(reader), Some(writer)) } else { diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs deleted file mode 100644 index 34a58f6c83aa7..0000000000000 --- a/src/libstd/sys/common/helper_thread.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementation of the helper thread for the timer module -//! -//! This module contains the management necessary for the timer worker thread. -//! This thread is responsible for performing the send()s on channels for timers -//! that are using channels instead of a blocking call. -//! -//! The timer thread is lazily initialized, and it's shut down via the -//! `shutdown` function provided. It must be maintained as an invariant that -//! `shutdown` is only called when the entire program is finished. No new timers -//! can be created in the future and there must be no active timers at that -//! time. - -use prelude::v1::*; - -use boxed; -use cell::UnsafeCell; -use rt; -use sync::{StaticMutex, StaticCondvar}; -use sync::mpsc::{channel, Sender, Receiver}; -use sys::helper_signal; - -use thread; - -/// A structure for management of a helper thread. -/// -/// This is generally a static structure which tracks the lifetime of a helper -/// thread. -/// -/// The fields of this helper are all public, but they should not be used, this -/// is for static initialization. -pub struct Helper { - /// Internal lock which protects the remaining fields - pub lock: StaticMutex, - pub cond: StaticCondvar, - - // You'll notice that the remaining fields are UnsafeCell, and this is - // because all helper thread operations are done through &self, but we need - // these to be mutable (once `lock` is held). - - /// Lazily allocated channel to send messages to the helper thread. - pub chan: UnsafeCell<*mut Sender>, - - /// OS handle used to wake up a blocked helper thread - pub signal: UnsafeCell, - - /// Flag if this helper thread has booted and been initialized yet. - pub initialized: UnsafeCell, - - /// Flag if this helper thread has shut down - pub shutdown: UnsafeCell, -} - -unsafe impl Send for Helper { } - -unsafe impl Sync for Helper { } - -struct RaceBox(helper_signal::signal); - -unsafe impl Send for RaceBox {} -unsafe impl Sync for RaceBox {} - -macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( - static $name: Helper<$m> = Helper { - lock: ::sync::MUTEX_INIT, - cond: ::sync::CONDVAR_INIT, - chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> }, - signal: ::cell::UnsafeCell { value: 0 }, - initialized: ::cell::UnsafeCell { value: false }, - shutdown: ::cell::UnsafeCell { value: false }, - }; -) } - -impl Helper { - /// Lazily boots a helper thread, becoming a no-op if the helper has already - /// been spawned. - /// - /// This function will check to see if the thread has been initialized, and - /// if it has it returns quickly. If initialization has not happened yet, - /// the closure `f` will be run (inside of the initialization lock) and - /// passed to the helper thread in a separate task. - /// - /// This function is safe to be called many times. - pub fn boot(&'static self, f: F, helper: fn(helper_signal::signal, Receiver, T)) where - T: Send + 'static, - F: FnOnce() -> T, - { - unsafe { - let _guard = self.lock.lock().unwrap(); - if *self.chan.get() as usize == 0 { - let (tx, rx) = channel(); - *self.chan.get() = boxed::into_raw(box tx); - let (receive, send) = helper_signal::new(); - *self.signal.get() = send as usize; - - let receive = RaceBox(receive); - - let t = f(); - thread::spawn(move || { - helper(receive.0, rx, t); - let _g = self.lock.lock().unwrap(); - *self.shutdown.get() = true; - self.cond.notify_one() - }); - - let _ = rt::at_exit(move || { self.shutdown() }); - *self.initialized.get() = true; - } else if *self.chan.get() as usize == 1 { - panic!("cannot continue usage after shutdown"); - } - } - } - - /// Sends a message to a spawned worker thread. - /// - /// This is only valid if the worker thread has previously booted - pub fn send(&'static self, msg: M) { - unsafe { - let _guard = self.lock.lock().unwrap(); - - // Must send and *then* signal to ensure that the child receives the - // message. Otherwise it could wake up and go to sleep before we - // send the message. - assert!(*self.chan.get() as usize != 0); - assert!(*self.chan.get() as usize != 1, - "cannot continue usage after shutdown"); - (**self.chan.get()).send(msg).unwrap(); - helper_signal::signal(*self.signal.get() as helper_signal::signal); - } - } - - fn shutdown(&'static self) { - unsafe { - // Shut down, but make sure this is done inside our lock to ensure - // that we'll always receive the exit signal when the thread - // returns. - let mut guard = self.lock.lock().unwrap(); - - let ptr = *self.chan.get(); - if ptr as usize == 1 { - panic!("cannot continue usage after shutdown"); - } - // Close the channel by destroying it - let chan = Box::from_raw(*self.chan.get()); - *self.chan.get() = 1 as *mut Sender; - drop(chan); - helper_signal::signal(*self.signal.get() as helper_signal::signal); - - // Wait for the child to exit - while !*self.shutdown.get() { - guard = self.cond.wait(guard).unwrap(); - } - drop(guard); - - // Clean up after ourselves - self.lock.destroy(); - helper_signal::close(*self.signal.get() as helper_signal::signal); - *self.signal.get() = 0; - } - } -} diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 95294b813ea19..b528575bbed33 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -15,7 +15,7 @@ use prelude::v1::*; pub mod backtrace; pub mod condvar; pub mod mutex; -pub mod net2; +pub mod net; pub mod poison; pub mod remutex; pub mod rwlock; diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net.rs similarity index 100% rename from src/libstd/sys/common/net2.rs rename to src/libstd/sys/common/net.rs diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs index 48c74b8d89eff..1a467580672b3 100644 --- a/src/libstd/sys/common/remutex.rs +++ b/src/libstd/sys/common/remutex.rs @@ -19,9 +19,9 @@ use sys::mutex as sys; /// A re-entrant mutual exclusion /// -/// This mutex will block *other* threads waiting for the lock to become available. The thread -/// which has already locked the mutex can lock it multiple times without blocking, preventing a -/// common source of deadlocks. +/// This mutex will block *other* threads waiting for the lock to become +/// available. The thread which has already locked the mutex can lock it +/// multiple times without blocking, preventing a common source of deadlocks. pub struct ReentrantMutex { inner: Box, poison: poison::Flag, @@ -51,10 +51,14 @@ impl<'a, T> !marker::Send for ReentrantMutexGuard<'a, T> {} impl ReentrantMutex { /// Creates a new reentrant mutex in an unlocked state. pub fn new(t: T) -> ReentrantMutex { - ReentrantMutex { - inner: box unsafe { sys::ReentrantMutex::new() }, - poison: poison::FLAG_INIT, - data: t, + unsafe { + let mut mutex = ReentrantMutex { + inner: box sys::ReentrantMutex::uninitialized(), + poison: poison::FLAG_INIT, + data: t, + }; + mutex.inner.init(); + return mutex } } diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 39910f509f9c2..a6953437497f6 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -102,7 +102,7 @@ impl OpenOptionsExt for OpenOptions { } #[unstable(feature = "metadata_ext", reason = "recently added API")] -pub struct Metadata(sys::fs2::FileAttr); +pub struct Metadata(sys::fs::FileAttr); #[unstable(feature = "metadata_ext", reason = "recently added API")] pub trait MetadataExt { @@ -111,7 +111,7 @@ pub trait MetadataExt { impl MetadataExt for fs::Metadata { fn as_raw(&self) -> &Metadata { - let inner: &sys::fs2::FileAttr = self.as_inner(); + let inner: &sys::fs::FileAttr = self.as_inner(); unsafe { mem::transmute(inner) } } } @@ -187,7 +187,7 @@ impl DirEntryExt for fs::DirEntry { #[stable(feature = "rust1", since = "1.0.0")] pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { - sys::fs2::symlink(src.as_ref(), dst.as_ref()) + sys::fs::symlink(src.as_ref(), dst.as_ref()) } #[unstable(feature = "dir_builder", reason = "recently added API")] diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs index c4a37241f6497..79e59ddab5be5 100644 --- a/src/libstd/sys/unix/ext/io.rs +++ b/src/libstd/sys/unix/ext/io.rs @@ -16,7 +16,7 @@ use fs; use net; use os::raw; use sys; -use sys_common::{net2, AsInner, FromInner}; +use sys_common::{self, AsInner, FromInner}; /// Raw file descriptors. #[stable(feature = "rust1", since = "1.0.0")] @@ -68,7 +68,7 @@ impl AsRawFd for fs::File { #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawFd for fs::File { unsafe fn from_raw_fd(fd: RawFd) -> fs::File { - fs::File::from_inner(sys::fs2::File::from_inner(fd)) + fs::File::from_inner(sys::fs::File::from_inner(fd)) } } @@ -89,20 +89,20 @@ impl AsRawFd for net::UdpSocket { impl FromRawFd for net::TcpStream { unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream { let socket = sys::net::Socket::from_inner(fd); - net::TcpStream::from_inner(net2::TcpStream::from_inner(socket)) + net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket)) } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawFd for net::TcpListener { unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener { let socket = sys::net::Socket::from_inner(fd); - net::TcpListener::from_inner(net2::TcpListener::from_inner(socket)) + net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket)) } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawFd for net::UdpSocket { unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket { let socket = sys::net::Socket::from_inner(fd); - net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket)) + net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket)) } } diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 8c9d0a86583fb..45d0d62a01575 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -58,7 +58,7 @@ pub trait ExitStatusExt { impl ExitStatusExt for process::ExitStatus { fn signal(&self) -> Option { match *self.as_inner() { - sys::process2::ExitStatus::Signal(s) => Some(s), + sys::process::ExitStatus::Signal(s) => Some(s), _ => None } } diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs.rs similarity index 100% rename from src/libstd/sys/unix/fs2.rs rename to src/libstd/sys/unix/fs.rs diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 78b798d3bffff..c1a4e8cee9ed4 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -33,13 +33,13 @@ pub mod c; pub mod condvar; pub mod ext; pub mod fd; -pub mod fs2; +pub mod fs; pub mod mutex; pub mod net; pub mod os; pub mod os_str; -pub mod pipe2; -pub mod process2; +pub mod pipe; +pub mod process; pub mod rwlock; pub mod stack_overflow; pub mod sync; diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index af814653c1466..70d14f63dbcc6 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -69,30 +69,27 @@ impl Mutex { } } -// FIXME: remove the box, because box happens twice now, once at the common layer and once here. -// Box is necessary here, because mutex may not change address after it is intialised on some -// platforms. Regular Mutex above handles this by offloading intialisation to the OS on first lock. -// Sadly, as far as reentrant mutexes go, this scheme is not quite portable and we must initialise -// when we create the mutex, in the `new`. -pub struct ReentrantMutex { inner: Box> } +pub struct ReentrantMutex { inner: UnsafeCell } unsafe impl Send for ReentrantMutex {} unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { - pub unsafe fn new() -> ReentrantMutex { - let mutex = ReentrantMutex { inner: box mem::uninitialized() }; + pub unsafe fn uninitialized() -> ReentrantMutex { + ReentrantMutex { inner: mem::uninitialized() } + } + + pub unsafe fn init(&mut self) { let mut attr: ffi::pthread_mutexattr_t = mem::uninitialized(); let result = ffi::pthread_mutexattr_init(&mut attr as *mut _); debug_assert_eq!(result, 0); let result = ffi::pthread_mutexattr_settype(&mut attr as *mut _, ffi::PTHREAD_MUTEX_RECURSIVE); debug_assert_eq!(result, 0); - let result = ffi::pthread_mutex_init(mutex.inner.get(), &attr as *const _); + let result = ffi::pthread_mutex_init(self.inner.get(), &attr as *const _); debug_assert_eq!(result, 0); let result = ffi::pthread_mutexattr_destroy(&mut attr as *mut _); debug_assert_eq!(result, 0); - mutex } pub unsafe fn lock(&self) { diff --git a/src/libstd/sys/unix/pipe2.rs b/src/libstd/sys/unix/pipe.rs similarity index 100% rename from src/libstd/sys/unix/pipe2.rs rename to src/libstd/sys/unix/pipe.rs diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process.rs similarity index 99% rename from src/libstd/sys/unix/process2.rs rename to src/libstd/sys/unix/process.rs index 6f3c0fd63aa6d..290310f4ad901 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process.rs @@ -18,9 +18,9 @@ use fmt; use io::{self, Error, ErrorKind}; use libc::{self, pid_t, c_void, c_int, gid_t, uid_t}; use ptr; -use sys::pipe2::AnonPipe; +use sys::pipe::AnonPipe; use sys::{self, c, cvt, cvt_r}; -use sys::fs2::{File, OpenOptions}; +use sys::fs::{File, OpenOptions}; //////////////////////////////////////////////////////////////////////////////// // Command @@ -141,7 +141,7 @@ impl Process { let (envp, _a, _b) = make_envp(cfg.env.as_ref()); let (argv, _a) = make_argv(&cfg.program, &cfg.args); - let (input, output) = try!(sys::pipe2::anon_pipe()); + let (input, output) = try!(sys::pipe::anon_pipe()); let pid = unsafe { match libc::fork() { diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 23c1fcf4b3c6e..822e1b370c2cf 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -125,7 +125,7 @@ impl MetadataExt for Metadata { #[stable(feature = "rust1", since = "1.0.0")] pub fn symlink_file, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { - sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), false) + sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), false) } /// Creates a new directory symlink on the filesystem. @@ -146,5 +146,5 @@ pub fn symlink_file, Q: AsRef>(src: P, dst: Q) #[stable(feature = "rust1", since = "1.0.0")] pub fn symlink_dir, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { - sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true) + sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), true) } diff --git a/src/libstd/sys/windows/ext/io.rs b/src/libstd/sys/windows/ext/io.rs index eb48022f05503..f4717eb2425e1 100644 --- a/src/libstd/sys/windows/ext/io.rs +++ b/src/libstd/sys/windows/ext/io.rs @@ -13,7 +13,7 @@ use fs; use os::windows::raw; use net; -use sys_common::{net2, AsInner, FromInner}; +use sys_common::{self, AsInner, FromInner}; use sys; /// Raw HANDLEs. @@ -61,7 +61,7 @@ impl AsRawHandle for fs::File { impl FromRawHandle for fs::File { unsafe fn from_raw_handle(handle: RawHandle) -> fs::File { let handle = handle as ::libc::HANDLE; - fs::File::from_inner(sys::fs2::File::from_inner(handle)) + fs::File::from_inner(sys::fs::File::from_inner(handle)) } } @@ -113,20 +113,20 @@ impl AsRawSocket for net::UdpSocket { impl FromRawSocket for net::TcpStream { unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream { let sock = sys::net::Socket::from_inner(sock); - net::TcpStream::from_inner(net2::TcpStream::from_inner(sock)) + net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock)) } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawSocket for net::TcpListener { unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener { let sock = sys::net::Socket::from_inner(sock); - net::TcpListener::from_inner(net2::TcpListener::from_inner(sock)) + net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock)) } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawSocket for net::UdpSocket { unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket { let sock = sys::net::Socket::from_inner(sock); - net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock)) + net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock)) } } diff --git a/src/libstd/sys/windows/fs2.rs b/src/libstd/sys/windows/fs.rs similarity index 100% rename from src/libstd/sys/windows/fs2.rs rename to src/libstd/sys/windows/fs.rs diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 5ae5f6f201bad..4c30f0f86604f 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -25,14 +25,14 @@ pub mod backtrace; pub mod c; pub mod condvar; pub mod ext; -pub mod fs2; +pub mod fs; pub mod handle; pub mod mutex; pub mod net; pub mod os; pub mod os_str; -pub mod pipe2; -pub mod process2; +pub mod pipe; +pub mod process; pub mod rwlock; pub mod stack_overflow; pub mod sync; diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index ca20858bb5bc5..9d2624f94180e 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -59,16 +59,18 @@ impl Mutex { } } -pub struct ReentrantMutex { inner: Box> } +pub struct ReentrantMutex { inner: UnsafeCell } unsafe impl Send for ReentrantMutex {} unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { - pub unsafe fn new() -> ReentrantMutex { - let mutex = ReentrantMutex { inner: box mem::uninitialized() }; - ffi::InitializeCriticalSection(mutex.inner.get()); - mutex + pub unsafe fn uninitialized() -> ReentrantMutex { + mem::uninitialized() + } + + pub unsafe fn init(&mut self) { + ffi::InitializeCriticalSection(self.inner.get()); } pub unsafe fn lock(&self) { diff --git a/src/libstd/sys/windows/pipe2.rs b/src/libstd/sys/windows/pipe.rs similarity index 100% rename from src/libstd/sys/windows/pipe2.rs rename to src/libstd/sys/windows/pipe.rs diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process.rs similarity index 99% rename from src/libstd/sys/windows/process2.rs rename to src/libstd/sys/windows/process.rs index 5aad5f668dd41..032a349b00eff 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process.rs @@ -26,9 +26,9 @@ use path::Path; use ptr; use sync::{StaticMutex, MUTEX_INIT}; use sys::c; -use sys::fs2::{OpenOptions, File}; +use sys::fs::{OpenOptions, File}; use sys::handle::Handle; -use sys::pipe2::AnonPipe; +use sys::pipe::AnonPipe; use sys::stdio; use sys::{self, cvt}; use sys_common::{AsInner, FromInner};