diff options
Diffstat (limited to 'src/libstd')
78 files changed, 691 insertions, 536 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 9ba90c470f8..9b824f11b92 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -205,15 +205,16 @@ fn test_resize_policy() { /// A hash map implementation which uses linear probing with Robin /// Hood bucket stealing. /// -/// The hashes are all keyed by the task-local random number generator +/// The hashes are all keyed by the thread-local random number generator /// on creation by default. This means that the ordering of the keys is /// randomized, but makes the tables more resistant to /// denial-of-service attacks (Hash DoS). This behaviour can be /// overridden with one of the constructors. /// /// It is required that the keys implement the `Eq` and `Hash` traits, although -/// this can frequently be achieved by using `#[derive(Eq, Hash)]`. If you -/// implement these yourself, it is important that the following property holds: +/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`. +/// If you implement these yourself, it is important that the following +/// property holds: /// /// ```text /// k1 == k2 -> hash(k1) == hash(k2) @@ -250,26 +251,26 @@ fn test_resize_policy() { /// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot."); /// /// // check for a specific one. -/// if !book_reviews.contains_key(&("Les Misérables")) { +/// if !book_reviews.contains_key("Les Misérables") { /// println!("We've got {} reviews, but Les Misérables ain't one.", /// book_reviews.len()); /// } /// /// // oops, this review has a lot of spelling mistakes, let's delete it. -/// book_reviews.remove(&("The Adventures of Sherlock Holmes")); +/// book_reviews.remove("The Adventures of Sherlock Holmes"); /// /// // look up the values associated with some keys. /// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; -/// for book in to_find.iter() { +/// for book in &to_find { /// match book_reviews.get(book) { -/// Some(review) => println!("{}: {}", *book, *review), -/// None => println!("{} is unreviewed.", *book) +/// Some(review) => println!("{}: {}", book, review), +/// None => println!("{} is unreviewed.", book) /// } /// } /// /// // iterate over everything. -/// for (book, review) in book_reviews.iter() { -/// println!("{}: \"{}\"", *book, *review); +/// for (book, review) in &book_reviews { +/// println!("{}: \"{}\"", book, review); /// } /// ``` /// @@ -300,7 +301,7 @@ fn test_resize_policy() { /// vikings.insert(Viking::new("Harald", "Iceland"), 12); /// /// // Use derived implementation to print the status of the vikings. -/// for (viking, health) in vikings.iter() { +/// for (viking, health) in &vikings { /// println!("{:?} has {} hp", viking, health); /// } /// ``` @@ -1600,13 +1601,13 @@ impl RandomState { reason = "hashing an hash maps may be altered")] impl HashState for RandomState { type Hasher = SipHasher; + #[inline] fn hasher(&self) -> SipHasher { SipHasher::new_with_keys(self.k0, self.k1) } } -#[unstable(feature = "std_misc", - reason = "hashing an hash maps may be altered")] +#[stable(feature = "rust1", since = "1.0.0")] impl Default for RandomState { #[inline] fn default() -> RandomState { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index f7e43b38539..d6754f10335 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -31,10 +31,12 @@ use super::state::HashState; // to get rid of it properly. /// An implementation of a hash set using the underlying representation of a -/// HashMap where the value is (). As with the `HashMap` type, a `HashSet` -/// requires that the elements implement the `Eq` and `Hash` traits. This can -/// frequently be achieved by using `#[derive(Eq, Hash)]`. If you implement -/// these yourself, it is important that the following property holds: +/// HashMap where the value is (). +/// +/// As with the `HashMap` type, a `HashSet` requires that the elements +/// implement the `Eq` and `Hash` traits. This can frequently be achieved by +/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself, +/// it is important that the following property holds: /// /// ```text /// k1 == k2 -> hash(k1) == hash(k2) @@ -64,17 +66,17 @@ use super::state::HashState; /// books.insert("The Great Gatsby"); /// /// // Check for a specific one. -/// if !books.contains(&("The Winds of Winter")) { +/// if !books.contains("The Winds of Winter") { /// println!("We have {} books, but The Winds of Winter ain't one.", /// books.len()); /// } /// /// // Remove a book. -/// books.remove(&"The Odyssey"); +/// books.remove("The Odyssey"); /// /// // Iterate over everything. -/// for book in books.iter() { -/// println!("{}", *book); +/// for book in &books { +/// println!("{}", book); /// } /// ``` /// @@ -98,7 +100,7 @@ use super::state::HashState; /// vikings.insert(Viking { name: "Harald", power: 8 }); /// /// // Use derived implementation to print the vikings. -/// for x in vikings.iter() { +/// for x in &vikings { /// println!("{:?}", x); /// } /// ``` diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 48b95ce6439..1099bf108f1 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -271,7 +271,7 @@ //! ``` //! //! Iterators also provide a series of *adapter* methods for performing common -//! tasks to sequences. Among the adapters are functional favorites like `map`, +//! threads to sequences. Among the adapters are functional favorites like `map`, //! `fold`, `skip`, and `take`. Of particular interest to collections is the //! `rev` adapter, that reverses any iterator that supports this operation. Most //! collections provide reversible iterators as the way to iterate over them in diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 114d0dd79a0..82999a47e56 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -27,7 +27,7 @@ use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering}; use sync::{StaticMutex, MUTEX_INIT}; use sys::os as os_imp; -/// Returns the current working directory as a `Path`. +/// Returns the current working directory as a `PathBuf`. /// /// # Errors /// @@ -66,7 +66,7 @@ pub fn current_dir() -> io::Result<PathBuf> { /// println!("Successfully changed working directory to {}!", root.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn set_current_dir<P: AsRef<Path> + ?Sized>(p: &P) -> io::Result<()> { +pub fn set_current_dir<P: AsRef<Path>>(p: P) -> io::Result<()> { os_imp::chdir(p.as_ref()) } @@ -175,7 +175,7 @@ impl Iterator for VarsOs { /// } /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsRef<OsStr> { +pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> { match var_os(key) { Some(s) => s.into_string().map_err(VarError::NotUnicode), None => Err(VarError::NotPresent) @@ -197,7 +197,7 @@ pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsRef<OsStr> /// } /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsRef<OsStr> { +pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> { let _g = ENV_LOCK.lock(); os_imp::getenv(key.as_ref()) } @@ -253,9 +253,7 @@ impl Error for VarError { /// assert_eq!(env::var(key), Ok("VALUE".to_string())); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V) - where K: AsRef<OsStr>, V: AsRef<OsStr> -{ +pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) { let _g = ENV_LOCK.lock(); os_imp::setenv(k.as_ref(), v.as_ref()) } @@ -275,7 +273,7 @@ pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V) /// assert!(env::var(key).is_err()); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn remove_var<K: ?Sized>(k: &K) where K: AsRef<OsStr> { +pub fn remove_var<K: AsRef<OsStr>>(k: K) { let _g = ENV_LOCK.lock(); os_imp::unsetenv(k.as_ref()) } @@ -459,8 +457,8 @@ static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT; /// Sets the process exit code /// -/// Sets the exit code returned by the process if all supervised tasks -/// terminate successfully (without panicking). If the current root task panics +/// Sets the exit code returned by the process if all supervised threads +/// terminate successfully (without panicking). If the current root thread panics /// and is supervised by the scheduler then any user-specified exit status is /// ignored and the process exits with the default panic status. /// diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 9f09f464cfc..6d23df97000 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -47,19 +47,22 @@ // coherence challenge (e.g., specialization, neg impls, etc) we can // reconsider what crate these items belong in. -use boxed::Box; +use any::TypeId; +use boxed::{self, Box}; use convert::From; use fmt::{self, Debug, Display}; -use marker::{Send, Sync}; +use marker::{Send, Sync, Reflect}; +use mem::transmute; use num; -use option::Option; -use option::Option::None; +use option::Option::{self, Some, None}; +use result::Result::{self, Ok, Err}; +use raw::TraitObject; use str; use string::{self, String}; /// Base functionality for all errors in Rust. #[stable(feature = "rust1", since = "1.0.0")] -pub trait Error: Debug + Display { +pub trait Error: Debug + Display + Reflect { /// A short description of the error. /// /// The description should not contain newlines or sentence-ending @@ -71,6 +74,14 @@ pub trait Error: Debug + Display { /// The lower-level cause of this error, if any. #[stable(feature = "rust1", since = "1.0.0")] fn cause(&self) -> Option<&Error> { None } + + /// Get the `TypeId` of `self` + #[doc(hidden)] + #[unstable(feature = "core", + reason = "unclear whether to commit to this public implementation detail")] + fn type_id(&self) -> TypeId where Self: 'static { + TypeId::of::<Self>() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -136,7 +147,7 @@ impl Error for num::ParseIntError { #[stable(feature = "rust1", since = "1.0.0")] impl Error for num::ParseFloatError { fn description(&self) -> &str { - self.description() + self.__description() } } @@ -154,3 +165,112 @@ impl Error for string::FromUtf16Error { } } +// copied from any.rs +impl Error + 'static { + /// Returns true if the boxed type is the same as `T` + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn is<T: Error + 'static>(&self) -> bool { + // Get TypeId of the type this function is instantiated with + let t = TypeId::of::<T>(); + + // Get TypeId of the type in the trait object + let boxed = self.type_id(); + + // Compare both TypeIds on equality + t == boxed + } + + /// Returns some reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(transmute(to.data)) + } + } else { + None + } + } + + /// Returns some mutable reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(transmute(to.data)) + } + } else { + None + } + } +} + +impl Error + 'static + Send { + /// Forwards to the method defined on the type `Any`. + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn is<T: Error + 'static>(&self) -> bool { + <Error + 'static>::is::<T>(self) + } + + /// Forwards to the method defined on the type `Any`. + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { + <Error + 'static>::downcast_ref::<T>(self) + } + + /// Forwards to the method defined on the type `Any`. + #[unstable(feature = "error_downcast", reason = "recently added")] + #[inline] + pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { + <Error + 'static>::downcast_mut::<T>(self) + } +} + +impl Error { + #[inline] + #[unstable(feature = "error_downcast", reason = "recently added")] + /// Attempt to downcast the box to a concrete type. + pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let raw = boxed::into_raw(self); + let to: TraitObject = + transmute::<*mut Error, TraitObject>(raw); + + // Extract the data pointer + Ok(Box::from_raw(to.data as *mut T)) + } + } else { + Err(self) + } + } +} + +impl Error + Send { + #[inline] + #[unstable(feature = "error_downcast", reason = "recently added")] + /// Attempt to downcast the box to a concrete type. + pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error + Send>> { + let err: Box<Error> = self; + <Error>::downcast(err).map_err(|s| unsafe { + // reapply the Send marker + transmute::<Box<Error>, Box<Error + Send>>(s) + }) + } +} diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 2b15a4ff83e..fc5405ea7f6 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; @@ -643,7 +643,7 @@ impl Permissions { /// use std::fs::File; /// /// # fn foo() -> std::io::Result<()> { - /// let mut f = try!(File::create("foo.txt")); + /// let f = try!(File::create("foo.txt")); /// let metadata = try!(f.metadata()); /// let mut permissions = metadata.permissions(); /// diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index ed6023b2b81..43a26292618 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -13,6 +13,7 @@ use prelude::v1::*; use io::prelude::*; +use marker::Reflect; use cmp; use error; use fmt; @@ -118,7 +119,7 @@ impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug { } } -#[unstable(feature = "buf_seek", reason = "recently added")] +#[stable(feature = "rust1", since = "1.0.0")] impl<R: Seek> Seek for BufReader<R> { /// Seek to an offset, in bytes, in the underlying reader. /// @@ -282,8 +283,8 @@ impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug { } } -#[unstable(feature = "buf_seek", reason = "recently added")] -impl<W: Write+Seek> Seek for BufWriter<W> { +#[stable(feature = "rust1", since = "1.0.0")] +impl<W: Write + Seek> Seek for BufWriter<W> { /// Seek to the offset, in bytes, in the underlying writer. /// /// Seeking always writes out the internal buffer before seeking. @@ -322,7 +323,7 @@ impl<W> From<IntoInnerError<W>> for Error { } #[stable(feature = "rust1", since = "1.0.0")] -impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> { +impl<W: Reflect + Send + fmt::Debug> error::Error for IntoInnerError<W> { fn description(&self) -> &str { error::Error::description(self.error()) } @@ -432,15 +433,19 @@ impl<W: Read + Write> Read for InternalBufWriter<W> { /// infrequent calls to `read` and `write` on the underlying `Read+Write`. /// /// The output buffer will be written out when this stream is dropped. -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] pub struct BufStream<S: Write> { inner: BufReader<InternalBufWriter<S>> } +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] impl<S: Read + Write> BufStream<S> { /// Creates a new buffered stream with explicitly listed capacities for the /// reader/writer buffer. - #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S) -> BufStream<S> { let writer = BufWriter::with_capacity(writer_cap, inner); @@ -451,13 +456,11 @@ impl<S: Read + Write> BufStream<S> { /// Creates a new buffered stream with the default reader/writer buffer /// capacities. - #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: S) -> BufStream<S> { BufStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, inner) } /// Gets a reference to the underlying stream. - #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &S { let InternalBufWriter(ref w) = self.inner.inner; w.get_ref() @@ -469,7 +472,6 @@ impl<S: Read + Write> BufStream<S> { /// /// It is inadvisable to read directly from or write directly to the /// underlying stream. - #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut S { let InternalBufWriter(ref mut w) = self.inner.inner; w.get_mut() @@ -479,7 +481,6 @@ impl<S: Read + Write> BufStream<S> { /// /// The internal write buffer is written out before returning the stream. /// Any leftover data in the read buffer is lost. - #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> { let BufReader { inner: InternalBufWriter(w), buf, pos, cap } = self.inner; w.into_inner().map_err(|IntoInnerError(w, e)| { @@ -490,20 +491,26 @@ impl<S: Read + Write> BufStream<S> { } } -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] impl<S: Read + Write> BufRead for BufStream<S> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() } fn consume(&mut self, amt: usize) { self.inner.consume(amt) } } -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] impl<S: Read + Write> Read for BufStream<S> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.read(buf) } } -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] impl<S: Read + Write> Write for BufStream<S> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.inner.inner.get_mut().write(buf) @@ -513,7 +520,9 @@ impl<S: Read + Write> Write for BufStream<S> { } } -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "buf_stream", + reason = "unsure about semantics of buffering two directions, \ + leading to issues like #17136")] impl<S: Write> fmt::Debug for BufStream<S> where S: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let reader = &self.inner; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 561c37ad950..9089b417fcb 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -236,7 +236,7 @@ pub trait Read { /// Transforms this `Read` instance to an `Iterator` over `char`s. /// - /// This adaptor will attempt to interpret this reader as an UTF-8 encoded + /// This adaptor will attempt to interpret this reader as a UTF-8 encoded /// sequence of characters. The returned iterator will return `None` once /// EOF is reached for this reader. Otherwise each element yielded will be a /// `Result<char, E>` where `E` may contain information about what I/O error diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index a9dab8191fd..a14c472333c 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -355,13 +355,13 @@ impl<'a> Write for StderrLock<'a> { } } -/// Resets the task-local stderr handle to the specified writer +/// Resets the thread-local stderr handle to the specified writer /// -/// This will replace the current task's stderr handle, returning the old +/// This will replace the current thread's stderr handle, returning the old /// handle. All future calls to `panic!` and friends will emit their output to /// this specified handle. /// -/// Note that this does not need to be called for all new tasks; the default +/// Note that this does not need to be called for all new threads; the default /// output handle is to the process's stderr stream. #[unstable(feature = "set_stdio", reason = "this function may disappear completely or be replaced \ @@ -378,13 +378,13 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> { }) } -/// Resets the task-local stdout handle to the specified writer +/// Resets the thread-local stdout handle to the specified writer /// -/// This will replace the current task's stdout handle, returning the old +/// This will replace the current thread's stdout handle, returning the old /// handle. All future calls to `print!` and friends will emit their output to /// this specified handle. /// -/// Note that this does not need to be called for all new tasks; the default +/// Note that this does not need to be called for all new threads; the default /// output handle is to the process's stdout stream. #[unstable(feature = "set_stdio", reason = "this function may disappear completely or be replaced \ diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index fcebe9c5e98..32193b4089d 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -16,10 +16,10 @@ #![unstable(feature = "std_misc")] -/// The entry point for panic of Rust tasks. +/// The entry point for panic of Rust threads. /// -/// This macro is used to inject panic into a Rust task, causing the task to -/// unwind and panic entirely. Each task's panic can be reaped as the +/// This macro is used to inject panic into a Rust thread, causing the thread to +/// unwind and panic entirely. Each thread's panic can be reaped as the /// `Box<Any>` type, and the single-argument form of the `panic!` macro will be /// the value which is transmitted. /// @@ -38,10 +38,10 @@ #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable] -/// The entry point for panic of Rust tasks. +/// The entry point for panic of Rust threads. /// -/// This macro is used to inject panic into a Rust task, causing the task to -/// unwind and panic entirely. Each task's panic can be reaped as the +/// This macro is used to inject panic into a Rust thread, causing the thread to +/// unwind and panic entirely. Each thread's panic can be reaped as the /// `Box<Any>` type, and the single-argument form of the `panic!` macro will be /// the value which is transmitted. /// @@ -143,21 +143,23 @@ macro_rules! try { /// use std::sync::mpsc; /// /// // two placeholder functions for now -/// fn long_running_task() {} +/// fn long_running_thread() {} /// fn calculate_the_answer() -> u32 { 42 } /// /// let (tx1, rx1) = mpsc::channel(); /// let (tx2, rx2) = mpsc::channel(); /// -/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); }); +/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); }); /// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); }); /// -/// select! ( -/// _ = rx1.recv() => println!("the long running task finished first"), +/// select! { +/// _ = rx1.recv() => println!("the long running thread finished first"), /// answer = rx2.recv() => { /// println!("the answer was: {}", answer.unwrap()); /// } -/// ) +/// } +/// # drop(rx1.recv()); +/// # drop(rx2.recv()); /// ``` /// /// For more information about select, see the `std::sync::mpsc::Select` structure. @@ -434,7 +436,7 @@ pub mod builtin { /// Parse the current given file as an expression. /// - /// This is generally a bad idea, because it's going to behave unhygenically. + /// This is generally a bad idea, because it's going to behave unhygienically. /// /// # Examples /// diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 9fd69840f7f..bc13d966a10 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -113,10 +113,13 @@ impl Ipv4Addr { /// Returns true if the address appears to be globally routable. /// - /// Non-globally-routable networks include the private networks (10.0.0.0/8, - /// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8), - /// the link-local network (169.254.0.0/16), the broadcast address (255.255.255.255/32) and - /// the test networks used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24). + /// The following return false: + /// + /// - private address (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) + /// - the loopback address (127.0.0.0/8) + /// - the link-local address (169.254.0.0/16) + /// - the broadcast address (255.255.255.255/32) + /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24) pub fn is_global(&self) -> bool { !self.is_private() && !self.is_loopback() && !self.is_link_local() && !self.is_broadcast() && !self.is_documentation() @@ -139,7 +142,8 @@ impl Ipv4Addr { /// Returns true if this address is in a range designated for documentation. /// - /// This is defined in RFC 5737 + /// This is defined in RFC 5737: + /// /// - 192.0.2.0/24 (TEST-NET-1) /// - 198.51.100.0/24 (TEST-NET-2) /// - 203.0.113.0/24 (TEST-NET-3) @@ -171,7 +175,6 @@ impl Ipv4Addr { ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16, ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16) } - } #[stable(feature = "rust1", since = "1.0.0")] @@ -244,6 +247,21 @@ impl FromInner<libc::in_addr> for Ipv4Addr { } } +#[stable(feature = "ip_u32", since = "1.1.0")] +impl From<Ipv4Addr> for u32 { + fn from(ip: Ipv4Addr) -> u32 { + let ip = ip.octets(); + ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) + } +} + +#[stable(feature = "ip_u32", since = "1.1.0")] +impl From<u32> for Ipv4Addr { + fn from(ip: u32) -> Ipv4Addr { + Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8) + } +} + impl Ipv6Addr { /// Creates a new IPv6 address from eight 16-bit segments. /// @@ -284,9 +302,11 @@ impl Ipv6Addr { /// Returns true if the address appears to be globally routable. /// - /// Non-globally-routable networks include the loopback address; the - /// link-local, site-local, and unique local unicast addresses; and the - /// interface-, link-, realm-, admin- and site-local multicast addresses. + /// The following return false: + /// + /// - the loopback address + /// - link-local, site-local, and unique local unicast addresses + /// - interface-, link-, realm-, admin- and site-local multicast addresses pub fn is_global(&self) -> bool { match self.multicast_scope() { Some(Ipv6MulticastScope::Global) => true, @@ -315,9 +335,12 @@ impl Ipv6Addr { /// Returns true if the address is a globally routable unicast address. /// - /// Non-globally-routable unicast addresses include the loopback address, - /// the link-local addresses, the deprecated site-local addresses and the - /// unique local addresses. + /// The following return false: + /// + /// - the loopback address + /// - the link-local addresses + /// - the (deprecated) site-local addresses + /// - unique local addresses pub fn is_unicast_global(&self) -> bool { !self.is_multicast() && !self.is_loopback() && !self.is_unicast_link_local() @@ -738,4 +761,16 @@ mod tests { let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345); assert_eq!(Ok(vec![a]), tsa(a)); } + + #[test] + fn test_ipv4_to_int() { + let a = Ipv4Addr::new(127, 0, 0, 1); + assert_eq!(u32::from(a), 2130706433); + } + + #[test] + fn test_int_to_ipv4() { + let a = Ipv4Addr::new(127, 0, 0, 1); + assert_eq!(Ipv4Addr::from(2130706433), a); + } } diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index 2e7c0a2c80e..bff9774bcd0 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}; @@ -32,7 +32,7 @@ mod parser; /// Possible values which can be passed to the `shutdown` method of `TcpStream` /// and `UdpSocket`. -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Shutdown { /// Indicates that the reading portion of this stream/socket should be shut diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index 7c1667a603f..69f40d7e7be 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -61,7 +61,7 @@ impl<'a> Parser<'a> { } // Return result of first successful parser - fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T>>]) + fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T> + 'static>]) -> Option<T> { for pf in parsers.iter_mut() { match self.read_atomically(|p: &mut Parser| pf(p)) { @@ -291,7 +291,7 @@ impl<'a> Parser<'a> { } } -#[unstable(feature = "ip_addr", reason = "recent addition")] +#[stable(feature = "rust1", since = "1.0.0")] impl FromStr for IpAddr { type Err = AddrParseError; fn from_str(s: &str) -> Result<IpAddr, AddrParseError> { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 130e1eee8f9..28063c1edb3 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -14,9 +14,10 @@ use prelude::v1::*; 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 @@ -167,6 +168,12 @@ impl FromInner<net_imp::TcpStream> for TcpStream { fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) } } +impl fmt::Debug for TcpStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + impl TcpListener { /// Creates a new `TcpListener` which will be bound to the specified /// address. @@ -239,6 +246,12 @@ impl FromInner<net_imp::TcpListener> for TcpListener { } } +impl fmt::Debug for TcpListener { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + #[cfg(test)] mod tests { use prelude::v1::*; @@ -248,6 +261,7 @@ mod tests { use net::*; use net::test::{next_test_ip4, next_test_ip6}; use sync::mpsc::channel; + use sys_common::AsInner; use thread; fn each_ip(f: &mut FnMut(SocketAddr)) { @@ -430,7 +444,7 @@ mod tests { let _t = thread::spawn(move|| { let acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX) { - // Start another task to handle the connection + // Start another thread to handle the connection let _t = thread::spawn(move|| { let mut stream = t!(stream); let mut buf = [0]; @@ -464,7 +478,7 @@ mod tests { let _t = thread::spawn(move|| { for stream in acceptor.incoming().take(MAX) { - // Start another task to handle the connection + // Start another thread to handle the connection let _t = thread::spawn(move|| { let mut stream = t!(stream); let mut buf = [0]; @@ -724,7 +738,7 @@ mod tests { assert_eq!(t!(s2.read(&mut [0])), 0); tx.send(()).unwrap(); }); - // this should wake up the child task + // this should wake up the child thread t!(s.shutdown(Shutdown::Read)); // this test will never finish if the child doesn't wake up @@ -738,7 +752,7 @@ mod tests { each_ip(&mut |addr| { let accept = t!(TcpListener::bind(&addr)); - // Enqueue a task to write to a socket + // Enqueue a thread to write to a socket let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); @@ -818,4 +832,27 @@ mod tests { rx.recv().unwrap(); }) } + + #[test] + fn debug() { + let name = if cfg!(windows) {"socket"} else {"fd"}; + let socket_addr = next_test_ip4(); + + let listener = t!(TcpListener::bind(&socket_addr)); + let listener_inner = listener.0.socket().as_inner(); + let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}", + socket_addr, name, listener_inner); + assert_eq!(format!("{:?}", listener), compare); + + let mut stream = t!(TcpStream::connect(&("localhost", + socket_addr.port()))); + let stream_inner = stream.0.socket().as_inner(); + let compare = format!("TcpStream {{ addr: {:?}, \ + peer: {:?}, {}: {:?} }}", + stream.local_addr().unwrap(), + stream.peer_addr().unwrap(), + name, + stream_inner); + assert_eq!(format!("{:?}", stream), compare); + } } diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 0b04ecb1b72..67c7096904d 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -13,9 +13,10 @@ 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. @@ -136,6 +137,12 @@ impl FromInner<net_imp::UdpSocket> for UdpSocket { fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) } } +impl fmt::Debug for UdpSocket { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + #[cfg(test)] mod tests { use prelude::v1::*; @@ -144,6 +151,7 @@ mod tests { use net::*; use net::test::{next_test_ip4, next_test_ip6}; use sync::mpsc::channel; + use sys_common::AsInner; use thread; fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) { @@ -301,4 +309,16 @@ mod tests { serv_rx.recv().unwrap(); }) } + + #[test] + fn debug() { + let name = if cfg!(windows) {"socket"} else {"fd"}; + let socket_addr = next_test_ip4(); + + let udpsock = t!(UdpSocket::bind(&socket_addr)); + let udpsock_inner = udpsock.0.socket().as_inner(); + let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", + socket_addr, name, udpsock_inner); + assert_eq!(format!("{:?}", udpsock), compare); + } } diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0efc04ef83c..1ee3aab2727 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -21,7 +21,6 @@ use core::num; use intrinsics; use libc::c_int; use num::{FpCategory, ParseFloatError}; -use sys_common::FromInner; pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON}; pub use core::f32::{MIN_EXP, MAX_EXP, MIN_10_EXP}; @@ -77,7 +76,7 @@ impl f32 { /// Parses a float as with a given radix #[unstable(feature = "float_from_str_radix", reason = "recently moved API")] pub fn from_str_radix(s: &str, radix: u32) -> Result<f32, ParseFloatError> { - num::Float::from_str_radix(s, radix).map_err(FromInner::from_inner) + num::Float::from_str_radix(s, radix) } /// Returns `true` if this value is `NaN` and false otherwise. diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index e1497f3958d..398afcb553c 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -20,7 +20,6 @@ use core::num; use intrinsics; use libc::c_int; use num::{FpCategory, ParseFloatError}; -use sys_common::FromInner; pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON}; pub use core::f64::{MIN_EXP, MAX_EXP, MIN_10_EXP}; @@ -85,7 +84,7 @@ impl f64 { /// Parses a float as with a given radix #[unstable(feature = "float_from_str_radix", reason = "recently moved API")] pub fn from_str_radix(s: &str, radix: u32) -> Result<f64, ParseFloatError> { - num::Float::from_str_radix(s, radix).map_err(FromInner::from_inner) + num::Float::from_str_radix(s, radix) } /// Returns `true` if this value is `NaN` and false otherwise. diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index cd26be013c4..9a52a0214e9 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -16,16 +16,14 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] -use fmt; -use core::num; - pub use core::num::{Zero, One}; -pub use core::num::{FpCategory, ParseIntError}; +pub use core::num::{FpCategory, ParseIntError, ParseFloatError}; pub use core::num::{wrapping, Wrapping}; -#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; #[cfg(test)] use cmp::PartialEq; +#[cfg(test)] use fmt; #[cfg(test)] use marker::Copy; +#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; /// Helper function for testing numeric operations #[cfg(test)] @@ -43,31 +41,6 @@ pub fn test_num<T>(ten: T, two: T) where assert_eq!(ten.rem(two), ten % two); } -/// An error which can be returned when parsing a float. -#[derive(Debug, Clone, PartialEq)] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct ParseFloatError { inner: num::ParseFloatError } - -impl ::sys_common::FromInner<num::ParseFloatError> for ParseFloatError { - fn from_inner(inner: num::ParseFloatError) -> ParseFloatError { - ParseFloatError { inner: inner } - } -} - -impl ParseFloatError { - #[unstable(feature = "core", reason = "available through Error trait")] - pub fn description(&self) -> &str { - self.inner.description() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Display for ParseFloatError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.description().fmt(f) - } -} - #[cfg(test)] mod tests { use core::prelude::*; diff --git a/src/libstd/os/android/mod.rs b/src/libstd/os/android/mod.rs index 346a903c4d9..a94abba5d12 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 01ea542b3b7..1fe5fdd4e14 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 677f8b706cd..d5c7c581733 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/dragonfly/raw.rs b/src/libstd/os/dragonfly/raw.rs index 22c811ead43..86522cc1e79 100644 --- a/src/libstd/os/dragonfly/raw.rs +++ b/src/libstd/os/dragonfly/raw.rs @@ -11,7 +11,7 @@ //! Dragonfly-specific raw type definitions use os::raw::c_long; -use os::unix::raw::{pid_t, uid_t, gid_t}; +use os::unix::raw::{uid_t, gid_t}; pub type blkcnt_t = i64; pub type blksize_t = u32; diff --git a/src/libstd/os/freebsd/mod.rs b/src/libstd/os/freebsd/mod.rs index 73b6fd21137..28c9f8321f8 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/freebsd/raw.rs b/src/libstd/os/freebsd/raw.rs index a810eff45d3..a3b95738a1a 100644 --- a/src/libstd/os/freebsd/raw.rs +++ b/src/libstd/os/freebsd/raw.rs @@ -11,7 +11,7 @@ //! FreeBSD-specific raw type definitions use os::raw::c_long; -use os::unix::raw::{uid_t, gid_t, pid_t}; +use os::unix::raw::{uid_t, gid_t}; pub type blkcnt_t = i64; pub type blksize_t = i64; diff --git a/src/libstd/os/ios/mod.rs b/src/libstd/os/ios/mod.rs index d471cf12fe6..dd2878c6e38 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/ios/raw.rs b/src/libstd/os/ios/raw.rs index 3266b3846d8..a66e01b2c39 100644 --- a/src/libstd/os/ios/raw.rs +++ b/src/libstd/os/ios/raw.rs @@ -11,7 +11,7 @@ //! iOS-specific raw type definitions use os::raw::c_long; -use os::unix::raw::{uid_t, gid_t, pid_t}; +use os::unix::raw::{uid_t, gid_t}; pub type blkcnt_t = i64; pub type blksize_t = i32; diff --git a/src/libstd/os/linux/mod.rs b/src/libstd/os/linux/mod.rs index 43376a1baeb..d2f9bcc3bcf 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 adce5f22ebc..9589f4cf099 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 bc5ff5b25d2..6c96909f382 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 6baed039514..413bb72f6e1 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 1b1a1005590..5654a7a0229 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/os/openbsd/raw.rs b/src/libstd/os/openbsd/raw.rs index 632a8c336b7..0bdba9e3487 100644 --- a/src/libstd/os/openbsd/raw.rs +++ b/src/libstd/os/openbsd/raw.rs @@ -11,7 +11,7 @@ //! OpenBSD-specific raw type definitions use os::raw::c_long; -use os::unix::raw::{uid_t, gid_t, pid_t}; +use os::unix::raw::{uid_t, gid_t}; pub type blkcnt_t = i64; pub type blksize_t = u32; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 2ceb60cc3aa..8ccc387c902 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -358,7 +358,7 @@ pub fn is_separator(c: char) -> bool { c.is_ascii() && is_sep_byte(c as u8) } -/// The primary sperator for the current platform +/// The primary separator for the current platform #[stable(feature = "rust1", since = "1.0.0")] pub const MAIN_SEPARATOR: char = platform::MAIN_SEP; diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 09fa10dacf9..4a8cceb202f 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -19,7 +19,7 @@ //! ``` //! //! This means that the contents of std can be accessed from any context -//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, +//! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`, //! etc. //! //! Additionally, `std` contains a `prelude` module that reexports many of the diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 8f8699f4b9f..61398e16ba0 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/rand/os.rs b/src/libstd/rand/os.rs index a04bb6705b3..3c36f0f1d49 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -374,7 +374,7 @@ mod tests { txs.push(tx); thread::spawn(move|| { - // wait until all the tasks are ready to go. + // wait until all the threads are ready to go. rx.recv().unwrap(); // deschedule to attempt to interleave things as much @@ -394,7 +394,7 @@ mod tests { }); } - // start all the tasks + // start all the threads for tx in &txs { tx.send(()).unwrap(); } diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index a764b99e280..b24099505ed 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -238,7 +238,7 @@ pub mod eabi { -> uw::_Unwind_Reason_Code; } - #[lang="eh_personality"] + #[lang = "eh_personality"] #[no_mangle] // referenced from rust_try.ll #[allow(private_no_mangle_fns)] extern fn rust_eh_personality( @@ -292,7 +292,7 @@ pub mod eabi { -> uw::_Unwind_Reason_Code; } - #[lang="eh_personality"] + #[lang = "eh_personality"] #[no_mangle] // referenced from rust_try.ll pub extern "C" fn rust_eh_personality( version: c_int, @@ -345,7 +345,7 @@ pub mod eabi { -> uw::_Unwind_Reason_Code; } - #[lang="eh_personality"] + #[lang = "eh_personality"] #[no_mangle] // referenced from rust_try.ll #[allow(private_no_mangle_fns)] extern "C" fn rust_eh_personality( @@ -432,7 +432,7 @@ pub mod eabi { ) -> EXCEPTION_DISPOSITION; } - #[lang="eh_personality"] + #[lang = "eh_personality"] #[no_mangle] // referenced from rust_try.ll #[allow(private_no_mangle_fns)] extern "C" fn rust_eh_personality( @@ -590,7 +590,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, /// This is an unsafe and experimental API which allows for an arbitrary /// callback to be invoked when a thread panics. This callback is invoked on both /// the initial unwinding and a double unwinding if one occurs. Additionally, -/// the local `Task` will be in place for the duration of the callback, and +/// the local `Thread` will be in place for the duration of the callback, and /// the callback must ensure that it remains in place once the callback returns. /// /// Only a limited number of callbacks can be registered, and this function diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index 34fcf6cdadd..8360620c345 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -10,7 +10,7 @@ use sync::{Mutex, Condvar}; -/// A barrier enables multiple tasks to synchronize the beginning +/// A barrier enables multiple threads to synchronize the beginning /// of some computation. /// /// ``` @@ -128,7 +128,7 @@ mod tests { }); } - // At this point, all spawned tasks should be blocked, + // At this point, all spawned threads should be blocked, // so we shouldn't get anything from the port assert!(match rx.try_recv() { Err(TryRecvError::Empty) => true, diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 61932225d79..77aeeca7968 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -107,7 +107,7 @@ //! //! let (tx, rx) = sync_channel::<i32>(0); //! thread::spawn(move|| { -//! // This will wait for the parent task to start receiving +//! // This will wait for the parent thread to start receiving //! tx.send(53).unwrap(); //! }); //! rx.recv().unwrap(); @@ -253,7 +253,7 @@ // blocking. The implementation is essentially the entire blocking procedure // followed by an increment as soon as its woken up. The cancellation procedure // involves an increment and swapping out of to_wake to acquire ownership of the -// task to unblock. +// thread to unblock. // // Sadly this current implementation requires multiple allocations, so I have // seen the throughput of select() be much worse than it should be. I do not @@ -272,6 +272,7 @@ use error; use fmt; use mem; use cell::UnsafeCell; +use marker::Reflect; pub use self::select::{Select, Handle}; use self::select::StartResult; @@ -288,7 +289,7 @@ mod mpsc_queue; mod spsc_queue; /// The receiving-half of Rust's channel type. This half can only be owned by -/// one task +/// one thread #[stable(feature = "rust1", since = "1.0.0")] pub struct Receiver<T> { inner: UnsafeCell<Flavor<T>>, @@ -315,7 +316,7 @@ pub struct IntoIter<T> { } /// The sending-half of Rust's asynchronous channel type. This half can only be -/// owned by one task, but it can be cloned to send to other tasks. +/// owned by one thread, but it can be cloned to send to other threads. #[stable(feature = "rust1", since = "1.0.0")] pub struct Sender<T> { inner: UnsafeCell<Flavor<T>>, @@ -326,7 +327,7 @@ pub struct Sender<T> { unsafe impl<T: Send> Send for Sender<T> { } /// The sending-half of Rust's synchronous channel type. This half can only be -/// owned by one task, but it can be cloned to send to other tasks. +/// owned by one thread, but it can be cloned to send to other threads. #[stable(feature = "rust1", since = "1.0.0")] pub struct SyncSender<T> { inner: Arc<UnsafeCell<sync::Packet<T>>>, @@ -420,7 +421,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> { /// Creates a new asynchronous channel, returning the sender/receiver halves. /// /// All data sent on the sender will become available on the receiver, and no -/// send will block the calling task (this channel has an "infinite buffer"). +/// send will block the calling thread (this channel has an "infinite buffer"). /// /// # Examples /// @@ -955,8 +956,7 @@ impl<T> fmt::Display for SendError<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> error::Error for SendError<T> { - +impl<T: Send + Reflect> error::Error for SendError<T> { fn description(&self) -> &str { "sending on a closed channel" } @@ -991,7 +991,7 @@ impl<T> fmt::Display for TrySendError<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> error::Error for TrySendError<T> { +impl<T: Send + Reflect> error::Error for TrySendError<T> { fn description(&self) -> &str { match *self { @@ -1596,7 +1596,7 @@ mod tests { drop(rx); // destroy a shared tx2.send(()).unwrap(); }); - // make sure the other task has gone to sleep + // make sure the other thread has gone to sleep for _ in 0..5000 { thread::yield_now(); } // upgrade to a shared chan and send a message @@ -1604,7 +1604,7 @@ mod tests { drop(tx); t.send(()).unwrap(); - // wait for the child task to exit before we exit + // wait for the child thread to exit before we exit rx2.recv().unwrap(); } } @@ -2060,7 +2060,7 @@ mod sync_tests { drop(rx); // destroy a shared tx2.send(()).unwrap(); }); - // make sure the other task has gone to sleep + // make sure the other thread has gone to sleep for _ in 0..5000 { thread::yield_now(); } // upgrade to a shared chan and send a message @@ -2068,7 +2068,7 @@ mod sync_tests { drop(tx); t.send(()).unwrap(); - // wait for the child task to exit before we exit + // wait for the child thread to exit before we exit rx2.recv().unwrap(); } diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index 4ab5a796fcb..2c0da938cbf 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -28,7 +28,7 @@ //! A mostly lock-free multi-producer, single consumer queue. //! //! This module contains an implementation of a concurrent MPSC queue. This -//! queue can be used to share data between tasks, and is also used as the +//! queue can be used to share data between threads, and is also used as the //! building block of channels in rust. //! //! Note that the current implementation of this queue has a caveat of the `pop` diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs index ab45b722c45..7e9c017617d 100644 --- a/src/libstd/sync/mpsc/oneshot.rs +++ b/src/libstd/sync/mpsc/oneshot.rs @@ -23,7 +23,7 @@ /// # Implementation /// /// Oneshots are implemented around one atomic usize variable. This variable -/// indicates both the state of the port/chan but also contains any tasks +/// indicates both the state of the port/chan but also contains any threads /// blocked on the port. All atomic operations happen on this one word. /// /// In order to upgrade a oneshot channel, an upgrade is considered a disconnect @@ -55,7 +55,7 @@ const DISCONNECTED: usize = 2; // channel is disconnected OR upgraded // whoever changed the state. pub struct Packet<T> { - // Internal state of the chan/port pair (stores the blocked task as well) + // Internal state of the chan/port pair (stores the blocked thread as well) state: AtomicUsize, // One-shot data slot location data: Option<T>, @@ -139,7 +139,7 @@ impl<T> Packet<T> { } pub fn recv(&mut self) -> Result<T, Failure<T>> { - // Attempt to not block the task (it's a little expensive). If it looks + // Attempt to not block the thread (it's a little expensive). If it looks // like we're not empty, then immediately go through to `try_recv`. if self.state.load(Ordering::SeqCst) == EMPTY { let (wait_token, signal_token) = blocking::tokens(); @@ -317,8 +317,8 @@ impl<T> Packet<T> { } } - // Remove a previous selecting task from this port. This ensures that the - // blocked task will no longer be visible to any other threads. + // Remove a previous selecting thread from this port. This ensures that the + // blocked thread will no longer be visible to any other threads. // // The return value indicates whether there's data on this port. pub fn abort_selection(&mut self) -> Result<bool, Receiver<T>> { @@ -329,7 +329,7 @@ impl<T> Packet<T> { s @ DATA | s @ DISCONNECTED => s, - // If we've got a blocked task, then use an atomic to gain ownership + // If we've got a blocked thread, then use an atomic to gain ownership // of it (may fail) ptr => self.state.compare_and_swap(ptr, EMPTY, Ordering::SeqCst) }; @@ -338,7 +338,7 @@ impl<T> Packet<T> { // about it. match state { EMPTY => unreachable!(), - // our task used for select was stolen + // our thread used for select was stolen DATA => Ok(true), // If the other end has hung up, then we have complete ownership diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index fde99e11040..679cc550454 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -58,7 +58,7 @@ use core::prelude::*; -use core::cell::Cell; +use core::cell::{Cell, UnsafeCell}; use core::marker; use core::mem; use core::ptr; @@ -70,9 +70,13 @@ use sync::mpsc::blocking::{self, SignalToken}; /// The "receiver set" of the select interface. This structure is used to manage /// a set of receivers which are being selected over. pub struct Select { + inner: UnsafeCell<SelectInner>, + next_id: Cell<usize>, +} + +struct SelectInner { head: *mut Handle<'static, ()>, tail: *mut Handle<'static, ()>, - next_id: Cell<usize>, } impl !marker::Send for Select {} @@ -84,7 +88,7 @@ pub struct Handle<'rx, T:Send+'rx> { /// The ID of this handle, used to compare against the return value of /// `Select::wait()` id: usize, - selector: &'rx Select, + selector: *mut SelectInner, next: *mut Handle<'static, ()>, prev: *mut Handle<'static, ()>, added: bool, @@ -127,8 +131,10 @@ impl Select { /// ``` pub fn new() -> Select { Select { - head: ptr::null_mut(), - tail: ptr::null_mut(), + inner: UnsafeCell::new(SelectInner { + head: ptr::null_mut(), + tail: ptr::null_mut(), + }), next_id: Cell::new(1), } } @@ -141,7 +147,7 @@ impl Select { self.next_id.set(id + 1); Handle { id: id, - selector: self, + selector: self.inner.get(), next: ptr::null_mut(), prev: ptr::null_mut(), added: false, @@ -223,7 +229,7 @@ impl Select { // woken us up (although the wakeup is guaranteed to fail). // // This situation happens in the window of where a sender invokes - // increment(), sees -1, and then decides to wake up the task. After + // increment(), sees -1, and then decides to wake up the thread. After // all this is done, the sending thread will set `selecting` to // `false`. Until this is done, we cannot return. If we were to // return, then a sender could wake up a receiver which has gone @@ -250,7 +256,7 @@ impl Select { } } - fn iter(&self) -> Packets { Packets { cur: self.head } } + fn iter(&self) -> Packets { Packets { cur: unsafe { &*self.inner.get() }.head } } } impl<'rx, T: Send> Handle<'rx, T> { @@ -271,7 +277,7 @@ impl<'rx, T: Send> Handle<'rx, T> { /// while it is added to the `Select` set. pub unsafe fn add(&mut self) { if self.added { return } - let selector: &mut Select = mem::transmute(&*self.selector); + let selector = &mut *self.selector; let me: *mut Handle<'static, ()> = mem::transmute(&*self); if selector.head.is_null() { @@ -292,7 +298,7 @@ impl<'rx, T: Send> Handle<'rx, T> { pub unsafe fn remove(&mut self) { if !self.added { return } - let selector: &mut Select = mem::transmute(&*self.selector); + let selector = &mut *self.selector; let me: *mut Handle<'static, ()> = mem::transmute(&*self); if self.prev.is_null() { @@ -317,8 +323,10 @@ impl<'rx, T: Send> Handle<'rx, T> { impl Drop for Select { fn drop(&mut self) { - assert!(self.head.is_null()); - assert!(self.tail.is_null()); + unsafe { + assert!((&*self.inner.get()).head.is_null()); + assert!((&*self.inner.get()).tail.is_null()); + } } } diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs index 09a02923f14..41c79dd52c8 100644 --- a/src/libstd/sync/mpsc/shared.rs +++ b/src/libstd/sync/mpsc/shared.rs @@ -91,8 +91,8 @@ impl<T> Packet<T> { } // This function is used at the creation of a shared packet to inherit a - // previously blocked task. This is done to prevent spurious wakeups of - // tasks in select(). + // previously blocked thread. This is done to prevent spurious wakeups of + // threads in select(). // // This can only be called at channel-creation time pub fn inherit_blocker(&mut self, @@ -424,7 +424,7 @@ impl<T> Packet<T> { } } - // Cancels a previous task waiting on this port, returning whether there's + // Cancels a previous thread waiting on this port, returning whether there's // data on the port. // // This is similar to the stream implementation (hence fewer comments), but diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs index f4b9c7d45fd..b72da91c0a0 100644 --- a/src/libstd/sync/mpsc/spsc_queue.rs +++ b/src/libstd/sync/mpsc/spsc_queue.rs @@ -30,7 +30,7 @@ //! A single-producer single-consumer concurrent queue //! //! This module contains the implementation of an SPSC queue which can be used -//! concurrently between two tasks. This data structure is safe to use and +//! concurrently between two threads. This data structure is safe to use and //! enforces the semantics that there is one pusher and one popper. #![unstable(feature = "std_misc")] diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index 1200e71d9af..404814b4cd4 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -181,7 +181,7 @@ impl<T> Packet<T> { data => return data, } - // Welp, our channel has no data. Deschedule the current task and + // Welp, our channel has no data. Deschedule the current thread and // initiate the blocking protocol. let (wait_token, signal_token) = blocking::tokens(); if self.decrement(signal_token).is_ok() { @@ -385,7 +385,7 @@ impl<T> Packet<T> { } } - // Removes a previous task from being blocked in this port + // Removes a previous thread from being blocked in this port pub fn abort_selection(&mut self, was_upgrade: bool) -> Result<bool, Receiver<T>> { // If we're aborting selection after upgrading from a oneshot, then @@ -414,7 +414,7 @@ impl<T> Packet<T> { let prev = self.bump(steals + 1); // If we were previously disconnected, then we know for sure that there - // is no task in to_wake, so just keep going + // is no thread in to_wake, so just keep going let has_data = if prev == DISCONNECTED { assert_eq!(self.to_wake.load(Ordering::SeqCst), 0); true // there is data, that data is that we're disconnected @@ -428,7 +428,7 @@ impl<T> Packet<T> { // // If the previous count was positive then we're in a tougher // situation. A possible race is that a sender just incremented - // through -1 (meaning it's going to try to wake a task up), but it + // through -1 (meaning it's going to try to wake a thread up), but it // hasn't yet read the to_wake. In order to prevent a future recv() // from waking up too early (this sender picking up the plastered // over to_wake), we spin loop here waiting for to_wake to be 0. diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 4687df107f6..904eab1fd7e 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -19,7 +19,7 @@ /// which means that every successful send is paired with a successful recv. /// /// This flavor of channels defines a new `send_opt` method for channels which -/// is the method by which a message is sent but the task does not panic if it +/// is the method by which a message is sent but the thread does not panic if it /// cannot be delivered. /// /// Another major difference is that send() will *always* return back the data @@ -62,12 +62,12 @@ unsafe impl<T: Send> Sync for Packet<T> { } struct State<T> { disconnected: bool, // Is the channel disconnected yet? queue: Queue, // queue of senders waiting to send data - blocker: Blocker, // currently blocked task on this channel + blocker: Blocker, // currently blocked thread on this channel buf: Buffer<T>, // storage for buffered messages cap: usize, // capacity of this channel /// A curious flag used to indicate whether a sender failed or succeeded in - /// blocking. This is used to transmit information back to the task that it + /// blocking. This is used to transmit information back to the thread that it /// must dequeue its message from the buffer because it was not received. /// This is only relevant in the 0-buffer case. This obviously cannot be /// safely constructed, but it's guaranteed to always have a valid pointer @@ -84,7 +84,7 @@ enum Blocker { NoneBlocked } -/// Simple queue for threading tasks together. Nodes are stack-allocated, so +/// Simple queue for threading threads together. Nodes are stack-allocated, so /// this structure is not safe at all struct Queue { head: *mut Node, @@ -130,7 +130,7 @@ fn wait<'a, 'b, T>(lock: &'a Mutex<State<T>>, /// Wakes up a thread, dropping the lock at the correct time fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) { - // We need to be careful to wake up the waiting task *outside* of the mutex + // We need to be careful to wake up the waiting thread *outside* of the mutex // in case it incurs a context switch. drop(guard); token.signal(); @@ -298,7 +298,7 @@ impl<T> Packet<T> { }; mem::drop(guard); - // only outside of the lock do we wake up the pending tasks + // only outside of the lock do we wake up the pending threads pending_sender1.map(|t| t.signal()); pending_sender2.map(|t| t.signal()); } @@ -394,8 +394,8 @@ impl<T> Packet<T> { } } - // Remove a previous selecting task from this port. This ensures that the - // blocked task will no longer be visible to any other threads. + // Remove a previous selecting thread from this port. This ensures that the + // blocked thread will no longer be visible to any other threads. // // The return value indicates whether there's data on this port. pub fn abort_selection(&self) -> bool { @@ -446,7 +446,7 @@ impl<T> Buffer<T> { } //////////////////////////////////////////////////////////////////////////////// -// Queue, a simple queue to enqueue tasks with (stack-allocated nodes) +// Queue, a simple queue to enqueue threads with (stack-allocated nodes) //////////////////////////////////////////////////////////////////////////////// impl Queue { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 30c7407a96d..febf5f1b183 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -30,7 +30,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// /// The mutexes in this module implement a strategy called "poisoning" where a /// mutex is considered poisoned whenever a thread panics while holding the -/// lock. Once a mutex is poisoned, all other tasks are unable to access the +/// lock. Once a mutex is poisoned, all other threads are unable to access the /// data by default as it is likely tainted (some invariant is not being /// upheld). /// @@ -56,7 +56,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// // Spawn a few threads to increment a shared variable (non-atomically), and /// // let the main thread know once all increments are done. /// // -/// // Here we're using an Arc to share memory among tasks, and the data inside +/// // Here we're using an Arc to share memory among threads, and the data inside /// // the Arc is protected with a mutex. /// let data = Arc::new(Mutex::new(0)); /// @@ -69,7 +69,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// // which can access the shared state when the lock is held. /// // /// // We unwrap() the return value to assert that we are not expecting -/// // tasks to ever fail while holding the lock. +/// // threads to ever fail while holding the lock. /// let mut data = data.lock().unwrap(); /// *data += 1; /// if *data == N { @@ -112,7 +112,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// *guard += 1; /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct Mutex<T> { +pub struct Mutex<T: ?Sized> { // Note that this static mutex is in a *box*, not inlined into the struct // itself. Once a native mutex has been used once, its address can never // change (it can't be moved). This mutex type can be safely moved at any @@ -124,9 +124,9 @@ pub struct Mutex<T> { // these are the only places where `T: Send` matters; all other // functionality works fine on a single thread. -unsafe impl<T: Send> Send for Mutex<T> { } +unsafe impl<T: ?Sized + Send> Send for Mutex<T> { } -unsafe impl<T: Send> Sync for Mutex<T> { } +unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { } /// The static mutex type is provided to allow for static allocation of mutexes. /// @@ -164,7 +164,7 @@ pub struct StaticMutex { /// `Deref` and `DerefMut` implementations #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -pub struct MutexGuard<'a, T: 'a> { +pub struct MutexGuard<'a, T: ?Sized + 'a> { // funny underscores due to how Deref/DerefMut currently work (they // disregard field privacy). __lock: &'a StaticMutex, @@ -172,7 +172,7 @@ pub struct MutexGuard<'a, T: 'a> { __poison: poison::Guard, } -impl<'a, T> !marker::Send for MutexGuard<'a, T> {} +impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {} /// Static initialization of a mutex. This constant can be used to initialize /// other mutex constants. @@ -192,11 +192,13 @@ impl<T> Mutex<T> { data: UnsafeCell::new(t), } } +} - /// Acquires a mutex, blocking the current task until it is able to do so. +impl<T: ?Sized> Mutex<T> { + /// Acquires a mutex, blocking the current thread until it is able to do so. /// - /// This function will block the local task until it is available to acquire - /// the mutex. Upon returning, the task is the only task with the mutex + /// This function will block the local thread until it is available to acquire + /// the mutex. Upon returning, the thread is the only thread with the mutex /// held. An RAII guard is returned to allow scoped unlock of the lock. When /// the guard goes out of scope, the mutex will be unlocked. /// @@ -245,7 +247,7 @@ impl<T> Mutex<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Drop for Mutex<T> { +impl<T: ?Sized> Drop for Mutex<T> { fn drop(&mut self) { // This is actually safe b/c we know that there is no further usage of // this mutex (it's up to the user to arrange for a mutex to get @@ -255,12 +257,12 @@ impl<T> Drop for Mutex<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: fmt::Debug + 'static> fmt::Debug for Mutex<T> { +impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.try_lock() { - Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", *guard), + Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard), Err(TryLockError::Poisoned(err)) => { - write!(f, "Mutex {{ data: Poisoned({:?}) }}", **err.get_ref()) + write!(f, "Mutex {{ data: Poisoned({:?}) }}", &**err.get_ref()) }, Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}") } @@ -310,7 +312,7 @@ impl StaticMutex { } } -impl<'mutex, T> MutexGuard<'mutex, T> { +impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> { fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>) -> LockResult<MutexGuard<'mutex, T>> { @@ -325,7 +327,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'mutex, T> Deref for MutexGuard<'mutex, T> { +impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> { type Target = T; fn deref<'a>(&'a self) -> &'a T { @@ -333,14 +335,14 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> { } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> { +impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> { fn deref_mut<'a>(&'a mut self) -> &'a mut T { unsafe { &mut *self.__data.get() } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> Drop for MutexGuard<'a, T> { +impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { #[inline] fn drop(&mut self) { unsafe { @@ -350,11 +352,11 @@ impl<'a, T> Drop for MutexGuard<'a, T> { } } -pub fn guard_lock<'a, T>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex { +pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex { &guard.__lock.lock } -pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag { +pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag { &guard.__lock.poison } @@ -528,4 +530,16 @@ mod tests { let lock = arc.lock().unwrap(); assert_eq!(*lock, 2); } + + #[test] + fn test_mutex_unsized() { + let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]); + { + let b = &mut *mutex.lock().unwrap(); + b[0] = 4; + b[2] = 5; + } + let comp: &[i32] = &[4, 2, 5]; + assert_eq!(&*mutex.lock().unwrap(), comp); + } } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 2d712369228..57baedaad9c 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -55,13 +55,13 @@ impl Once { /// will be executed if this is the first time `call_once` has been called, /// and otherwise the routine will *not* be invoked. /// - /// This method will block the calling task if another initialization + /// This method will block the calling thread if another initialization /// routine is currently running. /// /// When this function returns, it is guaranteed that some initialization /// has run and completed (it may not be the closure specified). It is also /// guaranteed that any memory writes performed by the executed closure can - /// be reliably observed by other tasks at this point (there is a + /// be reliably observed by other threads at this point (there is a /// happens-before relation between the closure and code executing after the /// return). #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index a133bb01b61..625377df7d6 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -25,7 +25,7 @@ use sys_common::rwlock as sys; /// typically allows for read-only access (shared access). /// /// The type parameter `T` represents the data that this lock protects. It is -/// required that `T` satisfies `Send` to be shared across tasks and `Sync` to +/// required that `T` satisfies `Send` to be shared across threads and `Sync` to /// allow concurrent access through readers. The RAII guards returned from the /// locking methods implement `Deref` (and `DerefMut` for the `write` methods) /// to allow access to the contained of the lock. @@ -60,13 +60,13 @@ use sys_common::rwlock as sys; /// } // write lock is dropped here /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct RwLock<T> { +pub struct RwLock<T: ?Sized> { inner: Box<StaticRwLock>, data: UnsafeCell<T>, } -unsafe impl<T: Send + Sync> Send for RwLock<T> {} -unsafe impl<T: Send + Sync> Sync for RwLock<T> {} +unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {} +unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {} /// Structure representing a statically allocated RwLock. /// @@ -111,24 +111,24 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock { /// dropped. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -pub struct RwLockReadGuard<'a, T: 'a> { +pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell<T>, } -impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {} +impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {} /// RAII structure used to release the exclusive write access of a lock when /// dropped. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -pub struct RwLockWriteGuard<'a, T: 'a> { +pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell<T>, __poison: poison::Guard, } -impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {} +impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {} impl<T> RwLock<T> { /// Creates a new instance of an `RwLock<T>` which is unlocked. @@ -144,7 +144,9 @@ impl<T> RwLock<T> { pub fn new(t: T) -> RwLock<T> { RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) } } +} +impl<T: ?Sized> RwLock<T> { /// Locks this rwlock with shared read access, blocking the current thread /// until it can be acquired. /// @@ -169,14 +171,16 @@ impl<T> RwLock<T> { RwLockReadGuard::new(&*self.inner, &self.data) } - /// Attempts to acquire this lock with shared read access. + /// Attempts to acquire this rwlock with shared read access. + /// + /// If the access could not be granted at this time, then `Err` is returned. + /// Otherwise, an RAII guard is returned which will release the shared access + /// when it is dropped. /// - /// This function will never block and will return immediately if `read` - /// would otherwise succeed. Returns `Some` of an RAII guard which will - /// release the shared access of this thread when dropped, or `None` if the - /// access could not be granted. This method does not provide any - /// guarantees with respect to the ordering of whether contentious readers - /// or writers will acquire the lock first. + /// This function does not block. + /// + /// This function does not provide any guarantees with respect to the ordering + /// of whether contentious readers or writers will acquire the lock first. /// /// # Failure /// @@ -217,9 +221,14 @@ impl<T> RwLock<T> { /// Attempts to lock this rwlock with exclusive write access. /// - /// This function does not ever block, and it will return `None` if a call - /// to `write` would otherwise block. If successful, an RAII guard is - /// returned. + /// If the lock could not be acquired at this time, then `Err` is returned. + /// Otherwise, an RAII guard is returned which will release the lock when + /// it is dropped. + /// + /// This function does not block. + /// + /// This function does not provide any guarantees with respect to the ordering + /// of whether contentious readers or writers will acquire the lock first. /// /// # Failure /// @@ -230,7 +239,7 @@ impl<T> RwLock<T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> { - if unsafe { self.inner.lock.try_read() } { + if unsafe { self.inner.lock.try_write() } { Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data))) } else { Err(TryLockError::WouldBlock) @@ -250,19 +259,19 @@ impl<T> RwLock<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Drop for RwLock<T> { +impl<T: ?Sized> Drop for RwLock<T> { fn drop(&mut self) { unsafe { self.inner.lock.destroy() } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: fmt::Debug> fmt::Debug for RwLock<T> { +impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.try_read() { - Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", *guard), + Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", &*guard), Err(TryLockError::Poisoned(err)) => { - write!(f, "RwLock {{ data: Poisoned({:?}) }}", **err.get_ref()) + write!(f, "RwLock {{ data: Poisoned({:?}) }}", &**err.get_ref()) }, Err(TryLockError::WouldBlock) => write!(f, "RwLock {{ <locked> }}") } @@ -341,8 +350,7 @@ impl StaticRwLock { } } -impl<'rwlock, T> RwLockReadGuard<'rwlock, T> { - +impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> { poison::map_result(lock.poison.borrow(), |_| { @@ -353,8 +361,8 @@ impl<'rwlock, T> RwLockReadGuard<'rwlock, T> { }) } } -impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { +impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> { fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> { poison::map_result(lock.poison.borrow(), |guard| { @@ -368,33 +376,35 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> { +impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } + #[stable(feature = "rust1", since = "1.0.0")] -impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> { +impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } + #[stable(feature = "rust1", since = "1.0.0")] -impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> { +impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.__data.get() } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> Drop for RwLockReadGuard<'a, T> { +impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> { fn drop(&mut self) { unsafe { self.__lock.lock.read_unlock(); } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> Drop for RwLockWriteGuard<'a, T> { +impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> { fn drop(&mut self) { self.__lock.poison.done(&self.__poison); unsafe { self.__lock.lock.write_unlock(); } @@ -410,7 +420,7 @@ mod tests { use rand::{self, Rng}; use sync::mpsc::channel; use thread; - use sync::{Arc, RwLock, StaticRwLock, RW_LOCK_INIT}; + use sync::{Arc, RwLock, StaticRwLock, TryLockError, RW_LOCK_INIT}; #[test] fn smoke() { @@ -562,4 +572,33 @@ mod tests { let lock = arc.read().unwrap(); assert_eq!(*lock, 2); } + + #[test] + fn test_rwlock_unsized() { + let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]); + { + let b = &mut *rw.write().unwrap(); + b[0] = 4; + b[2] = 5; + } + let comp: &[i32] = &[4, 2, 5]; + assert_eq!(&*rw.read().unwrap(), comp); + } + + #[test] + fn test_rwlock_try_write() { + use mem::drop; + + let lock = RwLock::new(0isize); + let read_guard = lock.read().unwrap(); + + let write_result = lock.try_write(); + match write_result { + Err(TryLockError::WouldBlock) => (), + Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"), + Err(_) => assert!(false, "unexpected error"), + } + + drop(read_guard); + } } diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs deleted file mode 100644 index 34a58f6c83a..00000000000 --- 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<M:Send> { - /// Internal lock which protects the remaining fields - pub lock: StaticMutex, - pub cond: StaticCondvar, - - // You'll notice that the remaining fields are UnsafeCell<T>, 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<M>>, - - /// OS handle used to wake up a blocked helper thread - pub signal: UnsafeCell<usize>, - - /// Flag if this helper thread has booted and been initialized yet. - pub initialized: UnsafeCell<bool>, - - /// Flag if this helper thread has shut down - pub shutdown: UnsafeCell<bool>, -} - -unsafe impl<M:Send> Send for Helper<M> { } - -unsafe impl<M:Send> Sync for Helper<M> { } - -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<M: Send> Helper<M> { - /// 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<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receiver<M>, 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<M>; - 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 95294b813ea..b528575bbed 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 index 2b2c31d92ed..7da7071670a 100644 --- a/src/libstd/sys/common/net2.rs +++ b/src/libstd/sys/common/net.rs @@ -11,6 +11,7 @@ use prelude::v1::*; use ffi::{CStr, CString}; +use fmt; use io::{self, Error, ErrorKind}; use libc::{self, c_int, c_char, c_void, socklen_t}; use mem; @@ -268,6 +269,24 @@ impl FromInner<Socket> for TcpStream { } } +impl fmt::Debug for TcpStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut res = f.debug_struct("TcpStream"); + + if let Ok(addr) = self.socket_addr() { + res = res.field("addr", &addr); + } + + if let Ok(peer) = self.peer_addr() { + res = res.field("peer", &peer); + } + + let name = if cfg!(windows) {"socket"} else {"fd"}; + res = res.field(name, &self.inner.as_inner()); + res.finish() + } +} + //////////////////////////////////////////////////////////////////////////////// // TCP listeners //////////////////////////////////////////////////////////////////////////////// @@ -327,6 +346,20 @@ impl FromInner<Socket> for TcpListener { } } +impl fmt::Debug for TcpListener { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut res = f.debug_struct("TcpListener"); + + if let Ok(addr) = self.socket_addr() { + res = res.field("addr", &addr); + } + + let name = if cfg!(windows) {"socket"} else {"fd"}; + res = res.field(name, &self.inner.as_inner()); + res.finish() + } +} + //////////////////////////////////////////////////////////////////////////////// // UDP //////////////////////////////////////////////////////////////////////////////// @@ -445,3 +478,17 @@ impl FromInner<Socket> for UdpSocket { UdpSocket { inner: socket } } } + +impl fmt::Debug for UdpSocket { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut res = f.debug_struct("UdpSocket"); + + if let Ok(addr) = self.socket_addr() { + res = res.field("addr", &addr); + } + + let name = if cfg!(windows) {"socket"} else {"fd"}; + res = res.field(name, &self.inner.as_inner()); + res.finish() + } +} diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs index 6deb4a48007..67679c11a98 100644 --- a/src/libstd/sys/common/poison.rs +++ b/src/libstd/sys/common/poison.rs @@ -10,6 +10,7 @@ use prelude::v1::*; +use marker::Reflect; use cell::UnsafeCell; use error::{Error}; use fmt; @@ -54,7 +55,7 @@ pub struct Guard { /// A type of error which can be returned whenever a lock is acquired. /// -/// Both Mutexes and RwLocks are poisoned whenever a task fails while the lock +/// Both Mutexes and RwLocks are poisoned whenever a thread fails while the lock /// is held. The precise semantics for when a lock is poisoned is documented on /// each lock, but once a lock is poisoned then all future acquisitions will /// return this error. @@ -67,7 +68,7 @@ pub struct PoisonError<T> { /// `try_lock` method. #[stable(feature = "rust1", since = "1.0.0")] pub enum TryLockError<T> { - /// The lock could not be acquired because another task failed while holding + /// The lock could not be acquired because another thread failed while holding /// the lock. #[stable(feature = "rust1", since = "1.0.0")] Poisoned(PoisonError<T>), @@ -109,7 +110,7 @@ impl<T> fmt::Display for PoisonError<T> { } } -impl<T: Send> Error for PoisonError<T> { +impl<T: Send + Reflect> Error for PoisonError<T> { fn description(&self) -> &str { "poisoned lock: another task failed inside" } @@ -155,13 +156,13 @@ impl<T> fmt::Debug for TryLockError<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> fmt::Display for TryLockError<T> { +impl<T: Send + Reflect> fmt::Display for TryLockError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) } } -impl<T: Send> Error for TryLockError<T> { +impl<T: Send + Reflect> Error for TryLockError<T> { fn description(&self) -> &str { match *self { TryLockError::Poisoned(ref p) => p.description(), diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs index 48c74b8d89e..1a467580672 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<T> { inner: Box<sys::ReentrantMutex>, poison: poison::Flag, @@ -51,10 +51,14 @@ impl<'a, T> !marker::Send for ReentrantMutexGuard<'a, T> {} impl<T> ReentrantMutex<T> { /// Creates a new reentrant mutex in an unlocked state. pub fn new(t: T) -> ReentrantMutex<T> { - 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/common/stack.rs b/src/libstd/sys/common/stack.rs index 8dc3407db77..fadeebc8150 100644 --- a/src/libstd/sys/common/stack.rs +++ b/src/libstd/sys/common/stack.rs @@ -11,13 +11,13 @@ //! Rust stack-limit management //! //! Currently Rust uses a segmented-stack-like scheme in order to detect stack -//! overflow for rust tasks. In this scheme, the prologue of all functions are +//! overflow for rust threads. In this scheme, the prologue of all functions are //! preceded with a check to see whether the current stack limits are being //! exceeded. //! //! This module provides the functionality necessary in order to manage these //! stack limits (which are stored in platform-specific locations). The -//! functions here are used at the borders of the task lifetime in order to +//! functions here are used at the borders of the thread lifetime in order to //! manage these limits. //! //! This function is an unstable module because this scheme for stack overflow diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 56a952e6a7e..cb9239ed7ba 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -161,7 +161,7 @@ impl Wtf8Buf { Wtf8Buf { bytes: Vec::with_capacity(n) } } - /// Creates a WTF-8 string from an UTF-8 `String`. + /// Creates a WTF-8 string from a UTF-8 `String`. /// /// This takes ownership of the `String` and does not copy. /// @@ -171,7 +171,7 @@ impl Wtf8Buf { Wtf8Buf { bytes: string.into_bytes() } } - /// Creates a WTF-8 string from an UTF-8 `&str` slice. + /// Creates a WTF-8 string from a UTF-8 `&str` slice. /// /// This copies the content of the slice. /// @@ -245,7 +245,7 @@ impl Wtf8Buf { self.bytes.capacity() } - /// Append an UTF-8 slice at the end of the string. + /// Append a UTF-8 slice at the end of the string. #[inline] pub fn push_str(&mut self, other: &str) { self.bytes.push_all(other.as_bytes()) @@ -527,7 +527,7 @@ impl Wtf8 { } /// Lossily converts the string to UTF-8. - /// Returns an UTF-8 `&str` slice if the contents are well-formed in UTF-8. + /// Returns a UTF-8 `&str` slice if the contents are well-formed in UTF-8. /// /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”). /// diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index ca805ad0242..135ae1bf916 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -22,7 +22,7 @@ /// getting both accurate backtraces and accurate symbols across platforms. /// This route was not chosen in favor of the next option, however. /// -/// * We're already using libgcc_s for exceptions in rust (triggering task +/// * We're already using libgcc_s for exceptions in rust (triggering thread /// unwinding and running destructors on the stack), and it turns out that it /// conveniently comes with a function that also gives us a backtrace. All of /// these functions look like _Unwind_*, but it's not quite the full @@ -116,7 +116,7 @@ pub fn write(w: &mut Write) -> io::Result<()> { // while it doesn't requires lock for work as everything is // local, it still displays much nicer backtraces when a - // couple of tasks panic simultaneously + // couple of threads panic simultaneously static LOCK: StaticMutex = MUTEX_INIT; let _g = LOCK.lock(); diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 2e4ed38e50f..a6953437497 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) } } } @@ -138,11 +138,11 @@ impl Metadata { pub fn rdev(&self) -> raw::dev_t { self.0.raw().st_rdev as raw::dev_t } pub fn size(&self) -> raw::off_t { self.0.raw().st_size as raw::off_t } pub fn atime(&self) -> raw::time_t { self.0.raw().st_atime } - pub fn atime_nsec(&self) -> c_long { self.0.raw().st_atime } + pub fn atime_nsec(&self) -> c_long { self.0.raw().st_atime_nsec as c_long } pub fn mtime(&self) -> raw::time_t { self.0.raw().st_mtime } - pub fn mtime_nsec(&self) -> c_long { self.0.raw().st_mtime } + pub fn mtime_nsec(&self) -> c_long { self.0.raw().st_mtime_nsec as c_long } pub fn ctime(&self) -> raw::time_t { self.0.raw().st_ctime } - pub fn ctime_nsec(&self) -> c_long { self.0.raw().st_ctime } + pub fn ctime_nsec(&self) -> c_long { self.0.raw().st_ctime_nsec as c_long } pub fn blksize(&self) -> raw::blksize_t { self.0.raw().st_blksize as raw::blksize_t @@ -187,7 +187,7 @@ impl DirEntryExt for fs::DirEntry { #[stable(feature = "rust1", since = "1.0.0")] pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(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 8cb4b4907f6..79e59ddab5b 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")] @@ -41,8 +41,7 @@ pub trait AsRawFd { /// A trait to express the ability to construct an object from a raw file /// descriptor. -#[unstable(feature = "from_raw_os", - reason = "recent addition to std::os::unix::io")] +#[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawFd { /// Constructs a new instances of `Self` from the given raw file /// descriptor. @@ -56,6 +55,7 @@ pub trait FromRawFd { /// descriptor they are wrapping. Usage of this function could /// accidentally allow violating this contract which can cause memory /// unsafety in code that relies on it being true. + #[stable(feature = "from_raw_os", since = "1.1.0")] unsafe fn from_raw_fd(fd: RawFd) -> Self; } @@ -65,10 +65,10 @@ impl AsRawFd for fs::File { self.as_inner().fd().raw() } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[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)) } } @@ -85,24 +85,24 @@ impl AsRawFd for net::UdpSocket { fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[stable(feature = "from_raw_os", since = "1.1.0")] 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)) } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[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)) } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[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 8c9d0a86583..45d0d62a015 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<i32> { 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/fd.rs b/src/libstd/sys/unix/fd.rs index e5bdb554359..026380027d2 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -31,7 +31,7 @@ impl FileDesc { /// Extracts the actual filedescriptor without closing it. pub fn into_raw(self) -> c_int { let fd = self.fd; - unsafe { mem::forget(self) }; + mem::forget(self); fd } diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs.rs index 350161c751c..350161c751c 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs.rs diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 78b798d3bff..c1a4e8cee9e 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 af814653c14..70d14f63dbc 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<UnsafeCell<ffi::pthread_mutex_t>> } +pub struct ReentrantMutex { inner: UnsafeCell<ffi::pthread_mutex_t> } 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 index e9d8c69fefb..e9d8c69fefb 100644 --- a/src/libstd/sys/unix/pipe2.rs +++ b/src/libstd/sys/unix/pipe.rs diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process.rs index 4e7c4d241f5..290310f4ad9 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() { @@ -328,7 +328,7 @@ impl Process { }) { Ok(0) => None, Ok(n) if n == self.pid => Some(translate_status(status)), - Ok(n) => panic!("unkown pid: {}", n), + Ok(n) => panic!("unknown pid: {}", n), Err(e) => panic!("unknown waitpid error: {}", e), } } diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs index adf9da2d067..7bb9fb68c14 100644 --- a/src/libstd/sys/unix/rwlock.rs +++ b/src/libstd/sys/unix/rwlock.rs @@ -10,6 +10,7 @@ use prelude::v1::*; +use libc; use cell::UnsafeCell; use sys::sync as ffi; @@ -26,7 +27,23 @@ impl RWLock { #[inline] pub unsafe fn read(&self) { let r = ffi::pthread_rwlock_rdlock(self.inner.get()); - debug_assert_eq!(r, 0); + + // According to the pthread_rwlock_rdlock spec, this function **may** + // fail with EDEADLK if a deadlock is detected. On the other hand + // pthread mutexes will *never* return EDEADLK if they are initialized + // as the "fast" kind (which ours always are). As a result, a deadlock + // situation may actually return from the call to pthread_rwlock_rdlock + // instead of blocking forever (as mutexes and Windows rwlocks do). Note + // that not all unix implementations, however, will return EDEADLK for + // their rwlocks. + // + // We roughly maintain the deadlocking behavior by panicking to ensure + // that this lock acquisition does not succeed. + if r == libc::EDEADLK { + panic!("rwlock read lock would result in deadlock"); + } else { + debug_assert_eq!(r, 0); + } } #[inline] pub unsafe fn try_read(&self) -> bool { @@ -35,7 +52,12 @@ impl RWLock { #[inline] pub unsafe fn write(&self) { let r = ffi::pthread_rwlock_wrlock(self.inner.get()); - debug_assert_eq!(r, 0); + // see comments above for why we check for EDEADLK + if r == libc::EDEADLK { + panic!("rwlock write lock would result in deadlock"); + } else { + debug_assert_eq!(r, 0); + } } #[inline] pub unsafe fn try_write(&self) -> bool { @@ -49,21 +71,16 @@ impl RWLock { #[inline] pub unsafe fn write_unlock(&self) { self.read_unlock() } #[inline] - #[cfg(not(target_os = "dragonfly"))] - pub unsafe fn destroy(&self) { - let r = ffi::pthread_rwlock_destroy(self.inner.get()); - debug_assert_eq!(r, 0); - } - - #[inline] - #[cfg(target_os = "dragonfly")] pub unsafe fn destroy(&self) { - use libc; let r = ffi::pthread_rwlock_destroy(self.inner.get()); // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a // rwlock that was just initialized with // ffi::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked) // or pthread_rwlock_init() is called, this behaviour no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); + if cfg!(target_os = "dragonfly") { + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } } } diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 23c1fcf4b3c..822e1b370c2 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<P: AsRef<Path>, Q: AsRef<Path>>(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<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) #[stable(feature = "rust1", since = "1.0.0")] pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(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 b88a6316eee..f4717eb2425 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. @@ -33,8 +33,7 @@ pub trait AsRawHandle { } /// Construct I/O objects from raw handles. -#[unstable(feature = "from_raw_os", - reason = "recent addition to the std::os::windows::io module")] +#[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawHandle { /// Constructs a new I/O object from the specified raw handle. /// @@ -47,6 +46,7 @@ pub trait FromRawHandle { /// descriptor they are wrapping. Usage of this function could /// accidentally allow violating this contract which can cause memory /// unsafety in code that relies on it being true. + #[stable(feature = "from_raw_os", since = "1.1.0")] unsafe fn from_raw_handle(handle: RawHandle) -> Self; } @@ -57,11 +57,11 @@ impl AsRawHandle for fs::File { } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[stable(feature = "from_raw_os", since = "1.1.0")] 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)) } } @@ -74,7 +74,7 @@ pub trait AsRawSocket { } /// Create I/O objects from raw sockets. -#[unstable(feature = "from_raw_os", reason = "recent addition to module")] +#[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawSocket { /// Creates a new I/O object from the given raw socket. /// @@ -86,6 +86,7 @@ pub trait FromRawSocket { /// descriptor they are wrapping. Usage of this function could /// accidentally allow violating this contract which can cause memory /// unsafety in code that relies on it being true. + #[stable(feature = "from_raw_os", since = "1.1.0")] unsafe fn from_raw_socket(sock: RawSocket) -> Self; } @@ -108,24 +109,24 @@ impl AsRawSocket for net::UdpSocket { } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[stable(feature = "from_raw_os", since = "1.1.0")] 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)) } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[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)) } } -#[unstable(feature = "from_raw_os", reason = "trait is unstable")] +#[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 index 03a56e2958a..03a56e2958a 100644 --- a/src/libstd/sys/windows/fs2.rs +++ b/src/libstd/sys/windows/fs.rs diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs index 9481e180ce5..c835d503388 100644 --- a/src/libstd/sys/windows/handle.rs +++ b/src/libstd/sys/windows/handle.rs @@ -32,7 +32,7 @@ impl Handle { pub fn into_raw(self) -> HANDLE { let ret = self.0; - unsafe { mem::forget(self) } + mem::forget(self); return ret; } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 5ae5f6f201b..4c30f0f8660 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 ca20858bb5b..9d2624f9418 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<UnsafeCell<ffi::CRITICAL_SECTION>> } +pub struct ReentrantMutex { inner: UnsafeCell<ffi::CRITICAL_SECTION> } 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 index b441d8beedb..b441d8beedb 100644 --- a/src/libstd/sys/windows/pipe2.rs +++ b/src/libstd/sys/windows/pipe.rs diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process.rs index 5aad5f668dd..032a349b00e 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}; diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index cbabab8acb7..ea5af3f2830 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -32,7 +32,7 @@ pub type Dtor = unsafe extern fn(*mut u8); // somewhere to run arbitrary code on thread termination. With this in place // we'll be able to run anything we like, including all TLS destructors! // -// To accomplish this feat, we perform a number of tasks, all contained +// To accomplish this feat, we perform a number of threads, all contained // within this module: // // * All TLS destructors are tracked by *us*, not the windows runtime. This diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index bb2832b8746..41bdf034705 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -32,7 +32,7 @@ pub mod __impl { /// primary method is the `with` method. /// /// The `with` method yields a reference to the contained value which cannot be -/// sent across tasks or escape the given closure. +/// sent across threads or escape the given closure. /// /// # Initialization and Destruction /// diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index bcc70c2b816..f480147b93e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -873,8 +873,8 @@ mod tests { #[test] fn test_child_doesnt_ref_parent() { - // If the child refcounts the parent task, this will stack overflow when - // climbing the task tree to dereference each ancestor. (See #1789) + // If the child refcounts the parent thread, this will stack overflow when + // climbing the thread tree to dereference each ancestor. (See #1789) // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) const GENERATIONS: u32 = 16; @@ -983,6 +983,6 @@ mod tests { thread::sleep_ms(2); } - // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due + // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due // to the test harness apparently interfering with stderr configuration. } |
