diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2015-02-18 23:50:21 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2015-02-18 23:50:21 +1100 |
| commit | dfc5c0f1e8799f47f9033bdcc8a7cd8a217620a5 (patch) | |
| tree | e9c32f2e58b3462a23dd9c472d2f236640b78811 /src/libstd | |
| parent | 6c065fc8cb036785f61ff03e05c1563cbb2dd081 (diff) | |
| parent | 47f91a9484eceef10536d4caac6ef578cd254567 (diff) | |
| download | rust-dfc5c0f1e8799f47f9033bdcc8a7cd8a217620a5.tar.gz rust-dfc5c0f1e8799f47f9033bdcc8a7cd8a217620a5.zip | |
Manual merge of #22475 - alexcrichton:rollup, r=alexcrichton
One windows bot failed spuriously.
Diffstat (limited to 'src/libstd')
60 files changed, 1868 insertions, 972 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 0a3abd5d1ac..4d38d17576d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -12,15 +12,12 @@ //! Operations on ASCII strings and characters -#![unstable(feature = "std_misc", - reason = "unsure about placement and naming")] +#![stable(feature = "rust1", since = "1.0.0")] -use iter::IteratorExt; -use ops::FnMut; -use slice::SliceExt; -use str::StrExt; -use string::String; -use vec::Vec; +use prelude::v1::*; + +use mem; +use iter::Range; /// Extension methods for ASCII-subset only operations on owned strings #[unstable(feature = "std_misc", @@ -38,31 +35,50 @@ pub trait OwnedAsciiExt { } /// Extension methods for ASCII-subset only operations on string slices -#[unstable(feature = "std_misc", - reason = "would prefer to do this in a more general way")] -pub trait AsciiExt<T = Self> { +#[stable(feature = "rust1", since = "1.0.0")] +pub trait AsciiExt { + #[stable(feature = "rust1", since = "1.0.0")] + type Owned; + /// Check if within the ASCII range. + #[stable(feature = "rust1", since = "1.0.0")] fn is_ascii(&self) -> bool; /// Makes a copy of the string in ASCII upper case: /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', /// but non-ASCII letters are unchanged. - fn to_ascii_uppercase(&self) -> T; + #[stable(feature = "rust1", since = "1.0.0")] + fn to_ascii_uppercase(&self) -> Self::Owned; /// Makes a copy of the string in ASCII lower case: /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', /// but non-ASCII letters are unchanged. - fn to_ascii_lowercase(&self) -> T; + #[stable(feature = "rust1", since = "1.0.0")] + fn to_ascii_lowercase(&self) -> Self::Owned; /// Check that two strings are an ASCII case-insensitive match. /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, /// but without allocating and copying temporary strings. + #[stable(feature = "rust1", since = "1.0.0")] fn eq_ignore_ascii_case(&self, other: &Self) -> bool; + + /// Convert this type to its ASCII upper case equivalent in-place. + /// + /// See `to_ascii_uppercase` for more information. + #[unstable(feature = "ascii")] + fn make_ascii_uppercase(&mut self); + + /// Convert this type to its ASCII lower case equivalent in-place. + /// + /// See `to_ascii_lowercase` for more information. + #[unstable(feature = "ascii")] + fn make_ascii_lowercase(&mut self); } -#[unstable(feature = "std_misc", - reason = "would prefer to do this in a more general way")] -impl AsciiExt<String> for str { +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for str { + type Owned = String; + #[inline] fn is_ascii(&self) -> bool { self.bytes().all(|b| b.is_ascii()) @@ -70,20 +86,28 @@ impl AsciiExt<String> for str { #[inline] fn to_ascii_uppercase(&self) -> String { - // Vec<u8>::to_ascii_uppercase() preserves the UTF-8 invariant. - unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_uppercase()) } + self.to_string().into_ascii_uppercase() } #[inline] fn to_ascii_lowercase(&self) -> String { - // Vec<u8>::to_ascii_lowercase() preserves the UTF-8 invariant. - unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_lowercase()) } + self.to_string().into_ascii_lowercase() } #[inline] fn eq_ignore_ascii_case(&self, other: &str) -> bool { self.as_bytes().eq_ignore_ascii_case(other.as_bytes()) } + + fn make_ascii_uppercase(&mut self) { + let me: &mut [u8] = unsafe { mem::transmute(self) }; + me.make_ascii_uppercase() + } + + fn make_ascii_lowercase(&mut self) { + let me: &mut [u8] = unsafe { mem::transmute(self) }; + me.make_ascii_lowercase() + } } #[unstable(feature = "std_misc", @@ -102,9 +126,9 @@ impl OwnedAsciiExt for String { } } -#[unstable(feature = "std_misc", - reason = "would prefer to do this in a more general way")] -impl AsciiExt<Vec<u8>> for [u8] { +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for [u8] { + type Owned = Vec<u8>; #[inline] fn is_ascii(&self) -> bool { self.iter().all(|b| b.is_ascii()) @@ -112,12 +136,12 @@ impl AsciiExt<Vec<u8>> for [u8] { #[inline] fn to_ascii_uppercase(&self) -> Vec<u8> { - self.iter().map(|b| b.to_ascii_uppercase()).collect() + self.to_vec().into_ascii_uppercase() } #[inline] fn to_ascii_lowercase(&self) -> Vec<u8> { - self.iter().map(|b| b.to_ascii_lowercase()).collect() + self.to_vec().into_ascii_lowercase() } #[inline] @@ -127,6 +151,18 @@ impl AsciiExt<Vec<u8>> for [u8] { a.eq_ignore_ascii_case(b) }) } + + fn make_ascii_uppercase(&mut self) { + for byte in self { + byte.make_ascii_uppercase(); + } + } + + fn make_ascii_lowercase(&mut self) { + for byte in self { + byte.make_ascii_lowercase(); + } + } } #[unstable(feature = "std_misc", @@ -134,48 +170,39 @@ impl AsciiExt<Vec<u8>> for [u8] { impl OwnedAsciiExt for Vec<u8> { #[inline] fn into_ascii_uppercase(mut self) -> Vec<u8> { - for byte in &mut self { - *byte = byte.to_ascii_uppercase(); - } + self.make_ascii_uppercase(); self } #[inline] fn into_ascii_lowercase(mut self) -> Vec<u8> { - for byte in &mut self { - *byte = byte.to_ascii_lowercase(); - } + self.make_ascii_lowercase(); self } } -#[unstable(feature = "std_misc", - reason = "would prefer to do this in a more general way")] +#[stable(feature = "rust1", since = "1.0.0")] impl AsciiExt for u8 { + type Owned = u8; #[inline] - fn is_ascii(&self) -> bool { - *self & 128 == 0u8 - } - + fn is_ascii(&self) -> bool { *self & 128 == 0u8 } #[inline] - fn to_ascii_uppercase(&self) -> u8 { - ASCII_UPPERCASE_MAP[*self as usize] - } - + fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] } #[inline] - fn to_ascii_lowercase(&self) -> u8 { - ASCII_LOWERCASE_MAP[*self as usize] - } - + fn to_ascii_lowercase(&self) -> u8 { ASCII_LOWERCASE_MAP[*self as usize] } #[inline] fn eq_ignore_ascii_case(&self, other: &u8) -> bool { self.to_ascii_lowercase() == other.to_ascii_lowercase() } + #[inline] + fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } + #[inline] + fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } } -#[unstable(feature = "std_misc", - reason = "would prefer to do this in a more general way")] +#[stable(feature = "rust1", since = "1.0.0")] impl AsciiExt for char { + type Owned = char; #[inline] fn is_ascii(&self) -> bool { *self as u32 <= 0x7F @@ -203,6 +230,19 @@ impl AsciiExt for char { fn eq_ignore_ascii_case(&self, other: &char) -> bool { self.to_ascii_lowercase() == other.to_ascii_lowercase() } + + #[inline] + fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } + #[inline] + fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } +} + +/// An iterator over the escaped version of a byte, constructed via +/// `std::ascii::escape_default`. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct EscapeDefault { + range: Range<usize>, + data: [u8; 4], } /// Returns a 'default' ASCII and C++11-like literal escape of a `u8` @@ -214,34 +254,46 @@ impl AsciiExt for char { /// - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively. /// - Single-quote, double-quote and backslash chars are backslash-escaped. /// - Any other chars in the range [0x20,0x7e] are not escaped. -/// - Any other chars are given hex escapes. +/// - Any other chars are given hex escapes of the form '\xNN'. /// - Unicode escapes are never generated by this function. -#[unstable(feature = "std_misc", - reason = "needs to be updated to use an iterator")] -pub fn escape_default<F>(c: u8, mut f: F) where - F: FnMut(u8), -{ - match c { - b'\t' => { f(b'\\'); f(b't'); } - b'\r' => { f(b'\\'); f(b'r'); } - b'\n' => { f(b'\\'); f(b'n'); } - b'\\' => { f(b'\\'); f(b'\\'); } - b'\'' => { f(b'\\'); f(b'\''); } - b'"' => { f(b'\\'); f(b'"'); } - b'\x20' ... b'\x7e' => { f(c); } - _ => { - f(b'\\'); - f(b'x'); - for &offset in &[4u, 0u] { - match ((c as i32) >> offset) & 0xf { - i @ 0 ... 9 => f(b'0' + (i as u8)), - i => f(b'a' + (i as u8 - 10)), - } - } +#[stable(feature = "rust1", since = "1.0.0")] +pub fn escape_default(c: u8) -> EscapeDefault { + let (data, len) = match c { + b'\t' => ([b'\\', b't', 0, 0], 2), + b'\r' => ([b'\\', b'r', 0, 0], 2), + b'\n' => ([b'\\', b'n', 0, 0], 2), + b'\\' => ([b'\\', b'\\', 0, 0], 2), + b'\'' => ([b'\\', b'\'', 0, 0], 2), + b'"' => ([b'\\', b'"', 0, 0], 2), + b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1), + _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4), + }; + + return EscapeDefault { range: range(0, len), data: data }; + + fn hexify(b: u8) -> u8 { + match b { + 0 ... 9 => b'0' + b, + _ => b'a' + b - 10, } } } +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for EscapeDefault { + type Item = u8; + fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) } + fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for EscapeDefault { + fn next_back(&mut self) -> Option<u8> { + self.range.next_back().map(|i| self.data[i]) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for EscapeDefault {} + static ASCII_LOWERCASE_MAP: [u8; 256] = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 241e409910f..1b9f8b99017 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1372,21 +1372,7 @@ enum VacantEntryState<K, V, M> { NoElem(EmptyBucket<K, V, M>), } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S> - where K: Eq + Hash<H>, - S: HashState<Hasher=H>, - H: hash::Hasher<Output=u64> -{ - type IntoIter = Iter<'a, K, V>; - - fn into_iter(self) -> Iter<'a, K, V> { - self.iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S> where K: Eq + Hash<H>, S: HashState<Hasher=H>, @@ -1400,21 +1386,7 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S> } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S> - where K: Eq + Hash<H>, - S: HashState<Hasher=H>, - H: hash::Hasher<Output=u64> -{ - type IntoIter = IterMut<'a, K, V>; - - fn into_iter(mut self) -> IterMut<'a, K, V> { - self.iter_mut() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S> where K: Eq + Hash<H>, S: HashState<Hasher=H>, @@ -1428,21 +1400,7 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S> } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<K, V, S, H> IntoIterator for HashMap<K, V, S> - where K: Eq + Hash<H>, - S: HashState<Hasher=H>, - H: hash::Hasher<Output=u64> -{ - type IntoIter = IntoIter<K, V>; - - fn into_iter(self) -> IntoIter<K, V> { - self.into_iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<K, V, S, H> IntoIterator for HashMap<K, V, S> where K: Eq + Hash<H>, S: HashState<Hasher=H>, diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 300e2089317..5fbbcb3b347 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -835,21 +835,7 @@ pub struct Union<'a, T: 'a, S: 'a> { iter: Chain<Iter<'a, T>, Difference<'a, T, S>> } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S> - where T: Eq + Hash<H>, - S: HashState<Hasher=H>, - H: hash::Hasher<Output=u64> -{ - type IntoIter = Iter<'a, T>; - - fn into_iter(self) -> Iter<'a, T> { - self.iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S> where T: Eq + Hash<H>, S: HashState<Hasher=H>, @@ -863,21 +849,7 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S> } } -// NOTE(stage0): remove impl after a snapshot -#[cfg(stage0)] -impl<T, S, H> IntoIterator for HashSet<T, S> - where T: Eq + Hash<H>, - S: HashState<Hasher=H>, - H: hash::Hasher<Output=u64> -{ - type IntoIter = IntoIter<T>; - - fn into_iter(self) -> IntoIter<T> { - self.into_iter() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[stable(feature = "rust1", since = "1.0.0")] impl<T, S, H> IntoIterator for HashSet<T, S> where T: Eq + Hash<H>, S: HashState<Hasher=H>, diff --git a/src/libstd/env.rs b/src/libstd/env.rs index ea18838211f..93dc3efe2c4 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -488,12 +488,20 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } } +impl ExactSizeIterator for Args { + fn len(&self) -> usize { self.inner.len() } +} + impl Iterator for ArgsOs { type Item = OsString; fn next(&mut self) -> Option<OsString> { self.inner.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } } +impl ExactSizeIterator for ArgsOs { + fn len(&self) -> usize { self.inner.len() } +} + /// Returns the page size of the current architecture in bytes. pub fn page_size() -> usize { os_imp::page_size() diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 5f91d173ed2..69791084e2f 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -114,7 +114,7 @@ impl File { /// Open a file in write-only mode. /// - /// This function will create a file it it does not exist, + /// This function will create a file if it does not exist, /// and will truncate it if it does. /// /// See the `OpenOptions::open` function for more details. diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 89c45f60d1c..c38d52161c9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -443,9 +443,8 @@ pub trait Seek { /// A seek beyond the end of a stream is allowed, but seeking before offset /// 0 is an error. /// - /// Seeking past the end of the stream does not modify the underlying - /// stream, but the next write may cause the previous data to be filled in - /// with a bit pattern. + /// The behavior when seeking past the end of the stream is implementation + /// defined. /// /// This method returns the new position within the stream if the seek /// operation completed successfully. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 139693ccdbc..7c9a8a7b4b5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -292,13 +292,6 @@ mod tuple; // can be resolved within libstd. #[doc(hidden)] mod std { - // NOTE: remove after next snapshot - // mods used for deriving - #[cfg(stage0)] pub use clone; - #[cfg(stage0)] pub use cmp; - #[cfg(stage0)] pub use hash; - #[cfg(stage0)] pub use default; - pub use sync; // used for select!() pub use error; // used for try!() pub use fmt; // used for any formatting strings @@ -319,7 +312,4 @@ mod std { pub use slice; pub use boxed; // used for vec![] - // for-loops - // NOTE: remove after next snapshot - #[cfg(stage0)] pub use iter; } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 6a2aafcf8f3..00bb7f86b17 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -60,23 +60,6 @@ macro_rules! panic { }); } -/// Use the syntax described in `std::fmt` to create a value of type `String`. -/// See `std::fmt` for more information. -/// -/// # Example -/// -/// ``` -/// format!("test"); -/// format!("hello {}", "world!"); -/// format!("x = {}, y = {y}", 10, y = 30); -/// ``` -#[cfg(stage0)] // NOTE: remove after snapshot -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -macro_rules! format { - ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*))) -} - /// Equivalent to the `println!` macro except that a newline is not printed at /// the end of the message. #[macro_export] @@ -126,7 +109,7 @@ macro_rules! try { /// # Examples /// /// ``` -/// use std::thread::Thread; +/// use std::thread; /// use std::sync::mpsc; /// /// // two placeholder functions for now @@ -136,8 +119,8 @@ macro_rules! try { /// let (tx1, rx1) = mpsc::channel(); /// let (tx2, rx2) = mpsc::channel(); /// -/// Thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); }); -/// Thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); }); +/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); }); +/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); }); /// /// select! ( /// _ = rx1.recv() => println!("the long running task finished first"), diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 50eafdfc5c2..b861b74947e 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -43,7 +43,7 @@ pub struct TcpStream(net_imp::TcpStream); /// /// ```no_run /// use std::net::{TcpListener, TcpStream}; -/// use std::thread::Thread; +/// use std::thread; /// /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); /// @@ -55,7 +55,7 @@ pub struct TcpStream(net_imp::TcpStream); /// for stream in listener.incoming() { /// match stream { /// Ok(stream) => { -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// // connection succeeded /// handle_client(stream) /// }); @@ -217,7 +217,7 @@ mod tests { use net::*; use net::test::{next_test_ip4, next_test_ip6}; use sync::mpsc::channel; - use thread::Thread; + use thread; fn each_ip(f: &mut FnMut(SocketAddr)) { f(next_test_ip4()); @@ -247,7 +247,8 @@ mod tests { fn connect_error() { match TcpStream::connect("0.0.0.0:1") { Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::ConnectionRefused), + Err(e) => assert!((e.kind() == ErrorKind::ConnectionRefused) + || (e.kind() == ErrorKind::InvalidInput)), } } @@ -256,7 +257,7 @@ mod tests { let socket_addr = next_test_ip4(); let listener = t!(TcpListener::bind(&socket_addr)); - let _t = Thread::scoped(move || { + let _t = thread::spawn(move || { let mut stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); t!(stream.write(&[144])); @@ -273,7 +274,7 @@ mod tests { let addr = next_test_ip4(); let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut stream = t!(TcpStream::connect(&("127.0.0.1", addr.port()))); t!(stream.write(&[44])); }); @@ -289,7 +290,7 @@ mod tests { let addr = next_test_ip6(); let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut stream = t!(TcpStream::connect(&("::1", addr.port()))); t!(stream.write(&[66])); }); @@ -306,7 +307,7 @@ mod tests { let acceptor = t!(TcpListener::bind(&addr)); let (tx, rx) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut stream = t!(TcpStream::connect(&addr)); t!(stream.write(&[99])); tx.send(t!(stream.socket_addr())).unwrap(); @@ -325,7 +326,7 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _stream = t!(TcpStream::connect(&addr)); // Close }); @@ -345,7 +346,7 @@ mod tests { let acceptor = t!(TcpListener::bind(&addr)); let (tx, rx) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { drop(t!(TcpStream::connect(&addr))); tx.send(()).unwrap(); }); @@ -371,7 +372,7 @@ mod tests { let max = 10; let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { for _ in 0..max { let mut stream = t!(TcpStream::connect(&addr)); t!(stream.write(&[99])); @@ -393,11 +394,11 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX) { // Start another task to handle the connection - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut stream = t!(stream); let mut buf = [0]; t!(stream.read(&mut buf)); @@ -412,7 +413,7 @@ mod tests { fn connect(i: usize, addr: SocketAddr) { if i == MAX { return } - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { let mut stream = t!(TcpStream::connect(&addr)); // Connect again before writing connect(i + 1, addr); @@ -428,10 +429,10 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { for stream in acceptor.incoming().take(MAX) { // Start another task to handle the connection - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut stream = t!(stream); let mut buf = [0]; t!(stream.read(&mut buf)); @@ -446,7 +447,7 @@ mod tests { fn connect(i: usize, addr: SocketAddr) { if i == MAX { return } - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { let mut stream = t!(TcpStream::connect(&addr)); connect(i + 1, addr); t!(stream.write(&[99])); @@ -467,7 +468,7 @@ mod tests { let listener = t!(TcpListener::bind(&addr)); let so_name = t!(listener.socket_addr()); assert_eq!(addr, so_name); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { t!(listener.accept()); }); @@ -481,7 +482,7 @@ mod tests { each_ip(&mut |addr| { let (tx, rx) = channel(); let srv = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut cl = t!(srv.accept()).0; cl.write(&[10]).unwrap(); let mut b = [0]; @@ -517,7 +518,7 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { t!(TcpStream::connect(&addr)); }); @@ -532,7 +533,7 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s = t!(TcpStream::connect(&addr)); let mut buf = [0, 0]; assert_eq!(s.read(&mut buf), Ok(1)); @@ -545,7 +546,7 @@ mod tests { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; rx1.recv().unwrap(); t!(s2.write(&[1])); @@ -565,7 +566,7 @@ mod tests { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s = t!(TcpStream::connect(&addr)); t!(s.write(&[1])); rx.recv().unwrap(); @@ -577,7 +578,7 @@ mod tests { let s2 = t!(s1.try_clone()); let (done, rx) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; let mut buf = [0, 0]; t!(s2.read(&mut buf)); @@ -597,7 +598,7 @@ mod tests { each_ip(&mut |addr| { let acceptor = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s = t!(TcpStream::connect(&addr)); let mut buf = [0, 1]; t!(s.read(&mut buf)); @@ -608,7 +609,7 @@ mod tests { let s2 = t!(s1.try_clone()); let (done, rx) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; t!(s2.write(&[1])); done.send(()).unwrap(); @@ -623,7 +624,7 @@ mod tests { fn shutdown_smoke() { each_ip(&mut |addr| { let a = t!(TcpListener::bind(&addr)); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut c = t!(a.accept()).0; let mut b = [0]; assert_eq!(c.read(&mut b), Ok(0)); @@ -644,7 +645,7 @@ mod tests { each_ip(&mut |addr| { let a = t!(TcpListener::bind(&addr)); let (tx, rx) = channel::<()>(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _s = t!(a.accept()); let _ = rx.recv(); }); @@ -682,7 +683,7 @@ mod tests { each_ip(&mut |addr| { let a = t!(TcpListener::bind(&addr)); let (tx1, rx) = channel::<()>(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _s = t!(a.accept()); let _ = rx.recv(); }); @@ -690,7 +691,7 @@ mod tests { let s = t!(TcpStream::connect(&addr)); let s2 = t!(s.try_clone()); let (tx, rx) = channel(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; assert_eq!(t!(s2.read(&mut [0])), 0); tx.send(()).unwrap(); @@ -713,7 +714,7 @@ mod tests { let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut tcp = t!(TcpStream::connect(&addr)); rx.recv().unwrap(); t!(tcp.write(&[0])); @@ -724,7 +725,7 @@ mod tests { let tcp = t!(accept.accept()).0; let tcp2 = t!(tcp.try_clone()); let txdone3 = txdone.clone(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let mut tcp2 = tcp2; t!(tcp2.read(&mut [0])); txdone3.send(()).unwrap(); @@ -732,7 +733,7 @@ mod tests { // Try to ensure that the reading clone is indeed reading for _ in 0..50 { - Thread::yield_now(); + thread::yield_now(); } // clone the handle again while it's reading, then let it finish the @@ -750,10 +751,10 @@ mod tests { let a = t!(TcpListener::bind(&addr)); let a2 = t!(a.try_clone()); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(&addr); }); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(&addr); }); @@ -771,17 +772,17 @@ mod tests { let (tx, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { tx.send(t!(a.accept())).unwrap(); }); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { tx2.send(t!(a2.accept())).unwrap(); }); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(&addr); }); - let _t = Thread::scoped(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(&addr); }); diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index d162a29790e..92f00599826 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -131,7 +131,7 @@ mod tests { use net::*; use net::test::{next_test_ip4, next_test_ip6}; use sync::mpsc::channel; - use thread::Thread; + use thread; fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) { f(next_test_ip4(), next_test_ip4()); @@ -164,7 +164,7 @@ mod tests { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let client = t!(UdpSocket::bind(&client_ip)); rx1.recv().unwrap(); t!(client.send_to(&[99], &server_ip)); @@ -196,7 +196,7 @@ mod tests { let sock1 = t!(UdpSocket::bind(&addr1)); let sock2 = t!(UdpSocket::bind(&addr2)); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut buf = [0, 0]; assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1))); assert_eq!(buf[0], 1); @@ -207,7 +207,7 @@ mod tests { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx1.recv().unwrap(); t!(sock3.send_to(&[1], &addr2)); tx2.send(()).unwrap(); @@ -227,7 +227,7 @@ mod tests { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { t!(sock2.send_to(&[1], &addr1)); rx.recv().unwrap(); t!(sock2.send_to(&[2], &addr1)); @@ -237,7 +237,7 @@ mod tests { let sock3 = t!(sock1.try_clone()); let (done, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut buf = [0, 0]; t!(sock3.recv_from(&mut buf)); tx2.send(()).unwrap(); @@ -260,7 +260,7 @@ mod tests { let (tx, rx) = channel(); let (serv_tx, serv_rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut buf = [0, 1]; rx.recv().unwrap(); t!(sock2.recv_from(&mut buf)); @@ -271,7 +271,7 @@ mod tests { let (done, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { match sock3.send_to(&[1], &addr2) { Ok(..) => { let _ = tx2.send(()); } Err(..) => {} diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 29532cb9b02..4582dcd2b03 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -51,71 +51,143 @@ pub trait Float + Rem<Output=Self> { // inlined methods from `num::Float` - /// Returns the NaN value. + /// Returns the `NaN` value. + /// + /// ``` + /// use std::num::Float; + /// + /// let nan: f32 = Float::nan(); + /// + /// assert!(nan.is_nan()); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn nan() -> Self; /// Returns the infinite value. + /// + /// ``` + /// use std::num::Float; + /// use std::f32; + /// + /// let infinity: f32 = Float::infinity(); + /// + /// assert!(infinity.is_infinite()); + /// assert!(!infinity.is_finite()); + /// assert!(infinity > f32::MAX); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn infinity() -> Self; /// Returns the negative infinite value. + /// + /// ``` + /// use std::num::Float; + /// use std::f32; + /// + /// let neg_infinity: f32 = Float::neg_infinity(); + /// + /// assert!(neg_infinity.is_infinite()); + /// assert!(!neg_infinity.is_finite()); + /// assert!(neg_infinity < f32::MIN); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn neg_infinity() -> Self; - /// Returns the `0` value. + /// Returns `0.0`. + /// + /// ``` + /// use std::num::Float; + /// + /// let inf: f32 = Float::infinity(); + /// let zero: f32 = Float::zero(); + /// let neg_zero: f32 = Float::neg_zero(); + /// + /// assert_eq!(zero, neg_zero); + /// assert_eq!(7.0f32/inf, zero); + /// assert_eq!(zero * 10.0, zero); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn zero() -> Self; - /// Returns -0.0. + /// Returns `-0.0`. + /// + /// ``` + /// use std::num::Float; + /// + /// let inf: f32 = Float::infinity(); + /// let zero: f32 = Float::zero(); + /// let neg_zero: f32 = Float::neg_zero(); + /// + /// assert_eq!(zero, neg_zero); + /// assert_eq!(7.0f32/inf, zero); + /// assert_eq!(zero * 10.0, zero); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn neg_zero() -> Self; - /// Returns the `1` value. + /// Returns `1.0`. + /// + /// ``` + /// use std::num::Float; + /// + /// let one: f32 = Float::one(); + /// + /// assert_eq!(one, 1.0f32); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn one() -> Self; // FIXME (#5527): These should be associated constants - /// Returns the number of binary digits of mantissa that this type supports. + /// Deprecated: use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS` + /// instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::MANTISSA_DIGITS` or \ `std::f64::MANTISSA_DIGITS` as appropriate")] fn mantissa_digits(unused_self: Option<Self>) -> uint; - /// Returns the number of base-10 digits of precision that this type supports. + /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")] fn digits(unused_self: Option<Self>) -> uint; - /// Returns the difference between 1.0 and the smallest representable number larger than 1.0. + /// Deprecated: use `std::f32::EPSILON` or `std::f64::EPSILON` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")] fn epsilon() -> Self; - /// Returns the minimum binary exponent that this type can represent. + /// Deprecated: use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")] fn min_exp(unused_self: Option<Self>) -> int; - /// Returns the maximum binary exponent that this type can represent. + /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")] fn max_exp(unused_self: Option<Self>) -> int; - /// Returns the minimum base-10 exponent that this type can represent. + /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")] fn min_10_exp(unused_self: Option<Self>) -> int; - /// Returns the maximum base-10 exponent that this type can represent. + /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead. #[unstable(feature = "std_misc")] #[deprecated(since = "1.0.0", reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")] fn max_10_exp(unused_self: Option<Self>) -> int; /// Returns the smallest finite value that this type can represent. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x: f64 = Float::min_value(); + /// + /// assert_eq!(x, f64::MIN); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn min_value() -> Self; @@ -124,50 +196,222 @@ pub trait Float reason = "unsure about its place in the world")] fn min_pos_value(unused_self: Option<Self>) -> Self; /// Returns the largest finite value that this type can represent. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x: f64 = Float::max_value(); + /// assert_eq!(x, f64::MAX); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn max_value() -> Self; - - /// Returns true if this value is NaN and false otherwise. + /// Returns `true` if this value is `NaN` and false otherwise. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let nan = f64::NAN; + /// let f = 7.0; + /// + /// assert!(nan.is_nan()); + /// assert!(!f.is_nan()); + /// ``` #[unstable(feature = "std_misc", reason = "position is undecided")] fn is_nan(self) -> bool; - /// Returns true if this value is positive infinity or negative infinity and + /// Returns `true` if this value is positive infinity or negative infinity and /// false otherwise. + /// + /// ``` + /// use std::num::Float; + /// use std::f32; + /// + /// let f = 7.0f32; + /// let inf: f32 = Float::infinity(); + /// let neg_inf: f32 = Float::neg_infinity(); + /// let nan: f32 = f32::NAN; + /// + /// assert!(!f.is_infinite()); + /// assert!(!nan.is_infinite()); + /// + /// assert!(inf.is_infinite()); + /// assert!(neg_inf.is_infinite()); + /// ``` #[unstable(feature = "std_misc", reason = "position is undecided")] fn is_infinite(self) -> bool; - /// Returns true if this number is neither infinite nor NaN. + /// Returns `true` if this number is neither infinite nor `NaN`. + /// + /// ``` + /// use std::num::Float; + /// use std::f32; + /// + /// let f = 7.0f32; + /// let inf: f32 = Float::infinity(); + /// let neg_inf: f32 = Float::neg_infinity(); + /// let nan: f32 = f32::NAN; + /// + /// assert!(f.is_finite()); + /// + /// assert!(!nan.is_finite()); + /// assert!(!inf.is_finite()); + /// assert!(!neg_inf.is_finite()); + /// ``` #[unstable(feature = "std_misc", reason = "position is undecided")] fn is_finite(self) -> bool; - /// Returns true if this number is neither zero, infinite, denormal, or NaN. + /// Returns `true` if the number is neither zero, infinite, + /// [subnormal][subnormal], or `NaN`. + /// + /// ``` + /// use std::num::Float; + /// use std::f32; + /// + /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32 + /// let max = f32::MAX; + /// let lower_than_min = 1.0e-40_f32; + /// let zero = 0.0f32; + /// + /// assert!(min.is_normal()); + /// assert!(max.is_normal()); + /// + /// assert!(!zero.is_normal()); + /// assert!(!f32::NAN.is_normal()); + /// assert!(!f32::INFINITY.is_normal()); + /// // Values between `0` and `min` are Subnormal. + /// assert!(!lower_than_min.is_normal()); + /// ``` + /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number #[unstable(feature = "std_misc", reason = "position is undecided")] fn is_normal(self) -> bool; - /// Returns the category that this number falls into. + + /// Returns the floating point category of the number. If only one property + /// is going to be tested, it is generally faster to use the specific + /// predicate instead. + /// + /// ``` + /// use std::num::{Float, FpCategory}; + /// use std::f32; + /// + /// let num = 12.4f32; + /// let inf = f32::INFINITY; + /// + /// assert_eq!(num.classify(), FpCategory::Normal); + /// assert_eq!(inf.classify(), FpCategory::Infinite); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn classify(self) -> FpCategory; - /// Returns the mantissa, exponent and sign as integers, respectively. + /// Returns the mantissa, base 2 exponent, and sign as integers, respectively. + /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`. + /// The floating point encoding is documented in the [Reference][floating-point]. + /// + /// ``` + /// use std::num::Float; + /// + /// let num = 2.0f32; + /// + /// // (8388608u64, -22i16, 1i8) + /// let (mantissa, exponent, sign) = num.integer_decode(); + /// let sign_f = sign as f32; + /// let mantissa_f = mantissa as f32; + /// let exponent_f = num.powf(exponent as f32); + /// + /// // 1 * 8388608 * 2^(-22) == 2 + /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` + /// [floating-point]: ../../../../../reference.html#machine-types #[unstable(feature = "std_misc", reason = "signature is undecided")] fn integer_decode(self) -> (u64, i16, i8); - /// Return the largest integer less than or equal to a number. + /// Returns the largest integer less than or equal to a number. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 3.99; + /// let g = 3.0; + /// + /// assert_eq!(f.floor(), 3.0); + /// assert_eq!(g.floor(), 3.0); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn floor(self) -> Self; - /// Return the smallest integer greater than or equal to a number. + /// Returns the smallest integer greater than or equal to a number. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 3.01; + /// let g = 4.0; + /// + /// assert_eq!(f.ceil(), 4.0); + /// assert_eq!(g.ceil(), 4.0); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn ceil(self) -> Self; - /// Return the nearest integer to a number. Round half-way cases away from + /// Returns the nearest integer to a number. Round half-way cases away from /// `0.0`. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 3.3; + /// let g = -3.3; + /// + /// assert_eq!(f.round(), 3.0); + /// assert_eq!(g.round(), -3.0); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn round(self) -> Self; /// Return the integer part of a number. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 3.3; + /// let g = -3.7; + /// + /// assert_eq!(f.trunc(), 3.0); + /// assert_eq!(g.trunc(), -3.0); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trunc(self) -> Self; - /// Return the fractional part of a number. + /// Returns the fractional part of a number. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 3.5; + /// let y = -3.5; + /// let abs_difference_x = (x.fract() - 0.5).abs(); + /// let abs_difference_y = (y.fract() - (-0.5)).abs(); + /// + /// assert!(abs_difference_x < 1e-10); + /// assert!(abs_difference_y < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn fract(self) -> Self; - /// Computes the absolute value of `self`. Returns `Float::nan()` if the /// number is `Float::nan()`. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = 3.5; + /// let y = -3.5; + /// + /// let abs_difference_x = (x.abs() - x).abs(); + /// let abs_difference_y = (y.abs() - (-y)).abs(); + /// + /// assert!(abs_difference_x < 1e-10); + /// assert!(abs_difference_y < 1e-10); + /// + /// assert!(f64::NAN.abs().is_nan()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn abs(self) -> Self; /// Returns a number that represents the sign of `self`. @@ -175,24 +419,88 @@ pub trait Float /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` /// - `Float::nan()` if the number is `Float::nan()` + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let f = 3.5; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f64::NAN.signum().is_nan()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn signum(self) -> Self; /// Returns `true` if `self` is positive, including `+0.0` and /// `Float::infinity()`. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let nan: f64 = f64::NAN; + /// + /// let f = 7.0; + /// let g = -7.0; + /// + /// assert!(f.is_positive()); + /// assert!(!g.is_positive()); + /// // Requires both tests to determine if is `NaN` + /// assert!(!nan.is_positive() && !nan.is_negative()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn is_positive(self) -> bool; /// Returns `true` if `self` is negative, including `-0.0` and /// `Float::neg_infinity()`. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let nan = f64::NAN; + /// + /// let f = 7.0; + /// let g = -7.0; + /// + /// assert!(!f.is_negative()); + /// assert!(g.is_negative()); + /// // Requires both tests to determine if is `NaN`. + /// assert!(!nan.is_positive() && !nan.is_negative()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn is_negative(self) -> bool; /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error. This produces a more accurate result with better performance than /// a separate multiplication operation followed by an add. + /// + /// ``` + /// use std::num::Float; + /// + /// let m = 10.0; + /// let x = 4.0; + /// let b = 60.0; + /// + /// // 100.0 + /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn mul_add(self, a: Self, b: Self) -> Self; /// Take the reciprocal (inverse) of a number, `1/x`. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 2.0; + /// let abs_difference = (x.recip() - (1.0/x)).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn recip(self) -> Self; @@ -200,149 +508,576 @@ pub trait Float /// Raise a number to an integer power. /// /// Using this function is generally faster than using `powf` + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 2.0; + /// let abs_difference = (x.powi(2) - x*x).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn powi(self, n: i32) -> Self; /// Raise a number to a floating point power. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 2.0; + /// let abs_difference = (x.powf(2.0) - x*x).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn powf(self, n: Self) -> Self; - /// Take the square root of a number. /// /// Returns NaN if `self` is a negative number. + /// + /// ``` + /// use std::num::Float; + /// + /// let positive = 4.0; + /// let negative = -4.0; + /// + /// let abs_difference = (positive.sqrt() - 2.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// assert!(negative.sqrt().is_nan()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn sqrt(self) -> Self; + /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 4.0; + /// + /// let abs_difference = (f.rsqrt() - 0.5).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn rsqrt(self) -> Self; /// Returns `e^(self)`, (the exponential function). + /// + /// ``` + /// use std::num::Float; + /// + /// let one = 1.0; + /// // e^1 + /// let e = one.exp(); + /// + /// // ln(e) - 1 == 0 + /// let abs_difference = (e.ln() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn exp(self) -> Self; - /// Returns 2 raised to the power of the number, `2^(self)`. + /// Returns `2^(self)`. + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 2.0; + /// + /// // 2^2 - 4 == 0 + /// let abs_difference = (f.exp2() - 4.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn exp2(self) -> Self; /// Returns the natural logarithm of the number. + /// + /// ``` + /// use std::num::Float; + /// + /// let one = 1.0; + /// // e^1 + /// let e = one.exp(); + /// + /// // ln(e) - 1 == 0 + /// let abs_difference = (e.ln() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn ln(self) -> Self; /// Returns the logarithm of the number with respect to an arbitrary base. + /// + /// ``` + /// use std::num::Float; + /// + /// let ten = 10.0; + /// let two = 2.0; + /// + /// // log10(10) - 1 == 0 + /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs(); + /// + /// // log2(2) - 1 == 0 + /// let abs_difference_2 = (two.log(2.0) - 1.0).abs(); + /// + /// assert!(abs_difference_10 < 1e-10); + /// assert!(abs_difference_2 < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn log(self, base: Self) -> Self; /// Returns the base 2 logarithm of the number. + /// + /// ``` + /// use std::num::Float; + /// + /// let two = 2.0; + /// + /// // log2(2) - 1 == 0 + /// let abs_difference = (two.log2() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn log2(self) -> Self; /// Returns the base 10 logarithm of the number. + /// + /// ``` + /// use std::num::Float; + /// + /// let ten = 10.0; + /// + /// // log10(10) - 1 == 0 + /// let abs_difference = (ten.log10() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn log10(self) -> Self; /// Convert radians to degrees. + /// + /// ``` + /// use std::num::Float; + /// use std::f64::consts; + /// + /// let angle = consts::PI; + /// + /// let abs_difference = (angle.to_degrees() - 180.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "desirability is unclear")] fn to_degrees(self) -> Self; /// Convert degrees to radians. + /// + /// ``` + /// use std::num::Float; + /// use std::f64::consts; + /// + /// let angle = 180.0; + /// + /// let abs_difference = (angle.to_radians() - consts::PI).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "desirability is unclear")] fn to_radians(self) -> Self; - - /// Constructs a floating point number created by multiplying `x` by 2 - /// raised to the power of `exp`. + /// Constructs a floating point number of `x*2^exp`. + /// + /// ``` + /// use std::num::Float; + /// + /// // 3*2^2 - 12 == 0 + /// let abs_difference = (Float::ldexp(3.0, 2) - 12.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "pending integer conventions")] fn ldexp(x: Self, exp: int) -> Self; /// Breaks the number into a normalized fraction and a base-2 exponent, /// satisfying: /// - /// * `self = x * pow(2, exp)` - /// + /// * `self = x * 2^exp` /// * `0.5 <= abs(x) < 1.0` + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 4.0; + /// + /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0 + /// let f = x.frexp(); + /// let abs_difference_0 = (f.0 - 0.5).abs(); + /// let abs_difference_1 = (f.1 as f64 - 3.0).abs(); + /// + /// assert!(abs_difference_0 < 1e-10); + /// assert!(abs_difference_1 < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "pending integer conventions")] fn frexp(self) -> (Self, int); - /// Returns the next representable floating-point value in the direction of /// `other`. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 1.0f32; + /// + /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs(); + /// + /// assert!(abs_diff < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn next_after(self, other: Self) -> Self; /// Returns the maximum of the two numbers. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 1.0; + /// let y = 2.0; + /// + /// assert_eq!(x.max(y), y); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn max(self, other: Self) -> Self; /// Returns the minimum of the two numbers. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 1.0; + /// let y = 2.0; + /// + /// assert_eq!(x.min(y), x); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn min(self, other: Self) -> Self; - /// The positive difference of two numbers. Returns `0.0` if the number is - /// less than or equal to `other`, otherwise the difference between`self` - /// and `other` is returned. + /// The positive difference of two numbers. + /// + /// * If `self <= other`: `0:0` + /// * Else: `self - other` + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 3.0; + /// let y = -3.0; + /// + /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs(); + /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs(); + /// + /// assert!(abs_difference_x < 1e-10); + /// assert!(abs_difference_y < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "may be renamed")] fn abs_sub(self, other: Self) -> Self; - /// Take the cubic root of a number. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 8.0; + /// + /// // x^(1/3) - 2 == 0 + /// let abs_difference = (x.cbrt() - 2.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "may be renamed")] fn cbrt(self) -> Self; /// Calculate the length of the hypotenuse of a right-angle triangle given /// legs of length `x` and `y`. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 2.0; + /// let y = 3.0; + /// + /// // sqrt(x^2 + y^2) + /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "unsure about its place in the world")] fn hypot(self, other: Self) -> Self; /// Computes the sine of a number (in radians). + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = f64::consts::PI/2.0; + /// + /// let abs_difference = (x.sin() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn sin(self) -> Self; /// Computes the cosine of a number (in radians). + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = 2.0*f64::consts::PI; + /// + /// let abs_difference = (x.cos() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn cos(self) -> Self; /// Computes the tangent of a number (in radians). + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = f64::consts::PI/4.0; + /// let abs_difference = (x.tan() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-14); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn tan(self) -> Self; - /// Computes the arcsine of a number. Return value is in radians in /// the range [-pi/2, pi/2] or NaN if the number is outside the range /// [-1, 1]. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let f = f64::consts::PI / 2.0; + /// + /// // asin(sin(pi/2)) + /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn asin(self) -> Self; /// Computes the arccosine of a number. Return value is in radians in /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let f = f64::consts::PI / 4.0; + /// + /// // acos(cos(pi/4)) + /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn acos(self) -> Self; /// Computes the arctangent of a number. Return value is in radians in the /// range [-pi/2, pi/2]; + /// + /// ``` + /// use std::num::Float; + /// + /// let f = 1.0; + /// + /// // atan(tan(1)) + /// let abs_difference = (f.tan().atan() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn atan(self) -> Self; - /// Computes the four quadrant arctangent of a number, `y`, and another - /// number `x`. Return value is in radians in the range [-pi, pi]. + /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). + /// + /// * `x = 0`, `y = 0`: `0` + /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` + /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` + /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let pi = f64::consts::PI; + /// // All angles from horizontal right (+x) + /// // 45 deg counter-clockwise + /// let x1 = 3.0; + /// let y1 = -3.0; + /// + /// // 135 deg clockwise + /// let x2 = -3.0; + /// let y2 = 3.0; + /// + /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs(); + /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs(); + /// + /// assert!(abs_difference_1 < 1e-10); + /// assert!(abs_difference_2 < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn atan2(self, other: Self) -> Self; /// Simultaneously computes the sine and cosine of the number, `x`. Returns /// `(sin(x), cos(x))`. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = f64::consts::PI/4.0; + /// let f = x.sin_cos(); + /// + /// let abs_difference_0 = (f.0 - x.sin()).abs(); + /// let abs_difference_1 = (f.1 - x.cos()).abs(); + /// + /// assert!(abs_difference_0 < 1e-10); + /// assert!(abs_difference_0 < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn sin_cos(self) -> (Self, Self); - /// Returns the exponential of the number, minus 1, in a way that is - /// accurate even if the number is close to zero. + /// Returns `e^(self) - 1` in a way that is accurate even if the + /// number is close to zero. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 7.0; + /// + /// // e^(ln(7)) - 1 + /// let abs_difference = (x.ln().exp_m1() - 6.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "may be renamed")] fn exp_m1(self) -> Self; - /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more - /// accurately than if the operations were performed separately. + /// Returns `ln(1+n)` (natural logarithm) more accurately than if + /// the operations were performed separately. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let x = f64::consts::E - 1.0; + /// + /// // ln(1 + (e - 1)) == ln(e) == 1 + /// let abs_difference = (x.ln_1p() - 1.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[unstable(feature = "std_misc", reason = "may be renamed")] fn ln_1p(self) -> Self; /// Hyperbolic sine function. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let e = f64::consts::E; + /// let x = 1.0; + /// + /// let f = x.sinh(); + /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` + /// let g = (e*e - 1.0)/(2.0*e); + /// let abs_difference = (f - g).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn sinh(self) -> Self; /// Hyperbolic cosine function. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let e = f64::consts::E; + /// let x = 1.0; + /// let f = x.cosh(); + /// // Solving cosh() at 1 gives this result + /// let g = (e*e + 1.0)/(2.0*e); + /// let abs_difference = (f - g).abs(); + /// + /// // Same result + /// assert!(abs_difference < 1.0e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn cosh(self) -> Self; /// Hyperbolic tangent function. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let e = f64::consts::E; + /// let x = 1.0; + /// + /// let f = x.tanh(); + /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` + /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2)); + /// let abs_difference = (f - g).abs(); + /// + /// assert!(abs_difference < 1.0e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn tanh(self) -> Self; /// Inverse hyperbolic sine function. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 1.0; + /// let f = x.sinh().asinh(); + /// + /// let abs_difference = (f - x).abs(); + /// + /// assert!(abs_difference < 1.0e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn asinh(self) -> Self; /// Inverse hyperbolic cosine function. + /// + /// ``` + /// use std::num::Float; + /// + /// let x = 1.0; + /// let f = x.cosh().acosh(); + /// + /// let abs_difference = (f - x).abs(); + /// + /// assert!(abs_difference < 1.0e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn acosh(self) -> Self; /// Inverse hyperbolic tangent function. + /// + /// ``` + /// use std::num::Float; + /// use std::f64; + /// + /// let e = f64::consts::E; + /// let f = e.tanh().atanh(); + /// + /// let abs_difference = (f - e).abs(); + /// + /// assert!(abs_difference < 1.0e-10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn atanh(self) -> Self; } diff --git a/src/libstd/old_io/comm_adapters.rs b/src/libstd/old_io/comm_adapters.rs index d8f9b1bb3fe..207d3d39167 100644 --- a/src/libstd/old_io/comm_adapters.rs +++ b/src/libstd/old_io/comm_adapters.rs @@ -161,12 +161,12 @@ mod test { use sync::mpsc::channel; use super::*; use old_io; - use thread::Thread; + use thread; #[test] fn test_rx_reader() { let (tx, rx) = channel(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(vec![1u8, 2u8]).unwrap(); tx.send(vec![]).unwrap(); tx.send(vec![3u8, 4u8]).unwrap(); @@ -208,7 +208,7 @@ mod test { #[test] fn test_rx_buffer() { let (tx, rx) = channel(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(b"he".to_vec()).unwrap(); tx.send(b"llo wo".to_vec()).unwrap(); tx.send(b"".to_vec()).unwrap(); @@ -234,10 +234,7 @@ mod test { writer.write_be_u32(42).unwrap(); let wanted = vec![0u8, 0u8, 0u8, 42u8]; - let got = match Thread::scoped(move|| { rx.recv().unwrap() }).join() { - Ok(got) => got, - Err(_) => panic!(), - }; + let got = thread::scoped(move|| { rx.recv().unwrap() }).join(); assert_eq!(wanted, got); match writer.write_u8(1) { diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index 3b35444df31..4bd0662232f 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -124,7 +124,7 @@ //! # #![allow(dead_code)] //! use std::old_io::{TcpListener, TcpStream}; //! use std::old_io::{Acceptor, Listener}; -//! use std::thread::Thread; +//! use std::thread; //! //! let listener = TcpListener::bind("127.0.0.1:80"); //! @@ -140,7 +140,7 @@ //! match stream { //! Err(e) => { /* connection failed */ } //! Ok(stream) => { -//! Thread::spawn(move|| { +//! thread::spawn(move|| { //! // connection succeeded //! handle_client(stream) //! }); @@ -238,7 +238,7 @@ //! concerned with error handling; instead its caller is responsible for //! responding to errors that may occur while attempting to read the numbers. -#![unstable(feature = "io")] +#![unstable(feature = "old_io")] #![deny(unused_must_use)] pub use self::SeekStyle::*; diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index 8c4a10a55d4..6b32d936c05 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -282,19 +282,19 @@ mod tests { use old_io::test::*; use super::*; use sync::mpsc::channel; - use thread::Thread; + use thread; use time::Duration; pub fn smalltest<F,G>(server: F, client: G) where F : FnOnce(UnixStream), F : Send, - G : FnOnce(UnixStream), G : Send + G : FnOnce(UnixStream), G : Send + 'static { let path1 = next_test_unix(); let path2 = path1.clone(); let mut acceptor = UnixListener::bind(&path1).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { match UnixStream::connect(&path2) { Ok(c) => client(c), Err(e) => panic!("failed connect: {}", e), @@ -389,7 +389,7 @@ mod tests { Err(e) => panic!("failed listen: {}", e), }; - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { for _ in 0u..times { let mut stream = UnixStream::connect(&path2); match stream.write(&[100]) { @@ -423,7 +423,7 @@ mod tests { let addr = next_test_unix(); let mut acceptor = UnixListener::bind(&addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = UnixStream::connect(&addr); let mut buf = [0, 0]; debug!("client reading"); @@ -439,7 +439,7 @@ mod tests { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; rx1.recv().unwrap(); debug!("writer writing"); @@ -462,7 +462,7 @@ mod tests { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = UnixStream::connect(&addr); s.write(&[1]).unwrap(); rx.recv().unwrap(); @@ -474,7 +474,7 @@ mod tests { let s2 = s1.clone(); let (done, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; let mut buf = [0, 0]; s2.read(&mut buf).unwrap(); @@ -493,7 +493,7 @@ mod tests { let addr = next_test_unix(); let mut acceptor = UnixListener::bind(&addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = UnixStream::connect(&addr); let buf = &mut [0, 1]; s.read(buf).unwrap(); @@ -504,7 +504,7 @@ mod tests { let s2 = s1.clone(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; s2.write(&[1]).unwrap(); tx.send(()).unwrap(); @@ -551,7 +551,7 @@ mod tests { // continue to receive any pending connections. let (tx, rx) = channel(); let addr2 = addr.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(UnixStream::connect(&addr2).unwrap()).unwrap(); }); let l = rx.recv().unwrap(); @@ -561,7 +561,7 @@ mod tests { Err(ref e) if e.kind == TimedOut => {} Err(e) => panic!("error: {}", e), } - ::thread::Thread::yield_now(); + ::thread::yield_now(); if i == 1000 { panic!("should have a pending connection") } } drop(l); @@ -569,7 +569,7 @@ mod tests { // Unset the timeout and make sure that this always blocks. a.set_timeout(None); let addr2 = addr.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(UnixStream::connect(&addr2).unwrap()); }); a.accept().unwrap(); @@ -607,7 +607,7 @@ mod tests { let addr = next_test_unix(); let a = UnixListener::bind(&addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv(); @@ -644,7 +644,7 @@ mod tests { let addr = next_test_unix(); let a = UnixListener::bind(&addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv(); @@ -653,7 +653,7 @@ mod tests { let mut s = UnixStream::connect(&addr).unwrap(); let s2 = s.clone(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_err()); tx.send(()).unwrap(); @@ -670,7 +670,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); @@ -708,7 +708,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv().unwrap(); let mut amt = 0; @@ -737,7 +737,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); @@ -764,7 +764,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); @@ -774,7 +774,7 @@ mod tests { let mut s = a.accept().unwrap(); let s2 = s.clone(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_ok()); tx2.send(()).unwrap(); @@ -796,10 +796,10 @@ mod tests { let mut a2 = a.clone(); let addr2 = addr.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = UnixStream::connect(&addr2); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = UnixStream::connect(&addr); }); @@ -819,20 +819,20 @@ mod tests { let (tx, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a; tx.send(a.accept()).unwrap() }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a2; tx2.send(a.accept()).unwrap() }); let addr2 = addr.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = UnixStream::connect(&addr2); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = UnixStream::connect(&addr); }); @@ -858,7 +858,7 @@ mod tests { let mut a2 = a.clone(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a; tx.send(a.accept()).unwrap(); }); diff --git a/src/libstd/old_io/net/tcp.rs b/src/libstd/old_io/net/tcp.rs index ebf7f6cc0f2..2afff9fc1c9 100644 --- a/src/libstd/old_io/net/tcp.rs +++ b/src/libstd/old_io/net/tcp.rs @@ -137,12 +137,12 @@ impl TcpStream { /// use std::old_io::timer; /// use std::old_io::TcpStream; /// use std::time::Duration; - /// use std::thread::Thread; + /// use std::thread; /// /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); /// let stream2 = stream.clone(); /// - /// let _t = Thread::spawn(move|| { + /// let _t = thread::spawn(move|| { /// // close this stream after one second /// timer::sleep(Duration::seconds(1)); /// let mut stream = stream2; @@ -282,7 +282,7 @@ impl sys_common::AsInner<TcpStreamImp> for TcpStream { /// # fn foo() { /// use std::old_io::{TcpListener, TcpStream}; /// use std::old_io::{Acceptor, Listener}; -/// use std::thread::Thread; +/// use std::thread; /// /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); /// @@ -298,7 +298,7 @@ impl sys_common::AsInner<TcpStreamImp> for TcpStream { /// match stream { /// Err(e) => { /* connection failed */ } /// Ok(stream) => { -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// // connection succeeded /// handle_client(stream) /// }); @@ -421,12 +421,12 @@ impl TcpAcceptor { /// /// ``` /// use std::old_io::{TcpListener, Listener, Acceptor, EndOfFile}; - /// use std::thread::Thread; + /// use std::thread; /// /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap(); /// let a2 = a.clone(); /// - /// let _t = Thread::spawn(move|| { + /// let _t = thread::spawn(move|| { /// let mut a2 = a2; /// for socket in a2.incoming() { /// match socket { @@ -487,13 +487,14 @@ mod test { use prelude::v1::*; use sync::mpsc::channel; - use thread::Thread; + use thread; use old_io::net::tcp::*; use old_io::net::ip::*; use old_io::test::*; use old_io::{EndOfFile, TimedOut, ShortWrite, IoError}; use old_io::{ConnectionRefused, BrokenPipe, ConnectionAborted}; use old_io::{ConnectionReset, NotConnected, PermissionDenied, OtherIoError}; + use old_io::{InvalidInput}; use old_io::{Acceptor, Listener}; // FIXME #11530 this fails on android because tests are run as root @@ -510,7 +511,8 @@ mod test { fn connect_error() { match TcpStream::connect("0.0.0.0:1") { Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind, ConnectionRefused), + Err(e) => assert!((e.kind == ConnectionRefused) + || (e.kind == InvalidInput)), } } @@ -520,7 +522,7 @@ mod test { let listener = TcpListener::bind(socket_addr); let mut acceptor = listener.listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(("localhost", socket_addr.port)); stream.write(&[144]).unwrap(); }); @@ -536,7 +538,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(("localhost", addr.port)); stream.write(&[64]).unwrap(); }); @@ -552,7 +554,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(("127.0.0.1", addr.port)); stream.write(&[44]).unwrap(); }); @@ -568,7 +570,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(("::1", addr.port)); stream.write(&[66]).unwrap(); }); @@ -584,7 +586,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); }); @@ -600,7 +602,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); }); @@ -616,7 +618,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -632,7 +634,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -648,7 +650,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -672,7 +674,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -697,7 +699,7 @@ mod test { let mut acceptor = TcpListener::bind(addr).listen(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(TcpStream::connect(addr)); tx.send(()).unwrap(); }); @@ -722,7 +724,7 @@ mod test { let mut acceptor = TcpListener::bind(addr).listen(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(TcpStream::connect(addr)); tx.send(()).unwrap(); }); @@ -747,7 +749,7 @@ mod test { let max = 10u; let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { for _ in 0..max { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); @@ -767,7 +769,7 @@ mod test { let max = 10u; let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { for _ in 0..max { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); @@ -787,11 +789,11 @@ mod test { static MAX: int = 10; let acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) { // Start another task to handle the connection - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -806,7 +808,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -823,11 +825,11 @@ mod test { static MAX: int = 10; let acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) { // Start another task to handle the connection - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -842,7 +844,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -859,11 +861,11 @@ mod test { let addr = next_test_ip4(); let acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acceptor = acceptor; for stream in acceptor.incoming().take(MAX as uint) { // Start another task to handle the connection - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -878,7 +880,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -895,11 +897,11 @@ mod test { let addr = next_test_ip6(); let acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acceptor = acceptor; for stream in acceptor.incoming().take(MAX as uint) { // Start another task to handle the connection - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -914,7 +916,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -937,7 +939,7 @@ mod test { pub fn peer_name(addr: SocketAddr) { let acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acceptor = acceptor; acceptor.accept().unwrap(); }); @@ -972,7 +974,7 @@ mod test { fn partial_read() { let addr = next_test_ip4(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut srv = TcpListener::bind(addr).listen().unwrap(); tx.send(()).unwrap(); let mut cl = srv.accept().unwrap(); @@ -1009,7 +1011,7 @@ mod test { let addr = next_test_ip4(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); let _stream = TcpStream::connect(addr).unwrap(); // Close @@ -1034,7 +1036,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = TcpStream::connect(addr); let mut buf = [0, 0]; assert_eq!(s.read(&mut buf), Ok(1)); @@ -1047,7 +1049,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; rx1.recv().unwrap(); s2.write(&[1]).unwrap(); @@ -1066,7 +1068,7 @@ mod test { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = TcpStream::connect(addr); s.write(&[1]).unwrap(); rx.recv().unwrap(); @@ -1078,7 +1080,7 @@ mod test { let s2 = s1.clone(); let (done, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; let mut buf = [0, 0]; s2.read(&mut buf).unwrap(); @@ -1097,7 +1099,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s = TcpStream::connect(addr); let mut buf = [0, 1]; s.read(&mut buf).unwrap(); @@ -1108,7 +1110,7 @@ mod test { let s2 = s1.clone(); let (done, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; s2.write(&[1]).unwrap(); done.send(()).unwrap(); @@ -1122,7 +1124,7 @@ mod test { fn shutdown_smoke() { let addr = next_test_ip4(); let a = TcpListener::bind(addr).unwrap().listen(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a; let mut c = a.accept().unwrap(); assert_eq!(c.read_to_end(), Ok(vec!())); @@ -1156,7 +1158,7 @@ mod test { // flakiness. if !cfg!(target_os = "freebsd") { let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(TcpStream::connect(addr).unwrap()).unwrap(); }); let _l = rx.recv().unwrap(); @@ -1166,14 +1168,14 @@ mod test { Err(ref e) if e.kind == TimedOut => {} Err(e) => panic!("error: {}", e), } - ::thread::Thread::yield_now(); + ::thread::yield_now(); if i == 1000 { panic!("should have a pending connection") } } } // Unset the timeout and make sure that this always blocks. a.set_timeout(None); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(TcpStream::connect(addr).unwrap()); }); a.accept().unwrap(); @@ -1184,7 +1186,7 @@ mod test { let addr = next_test_ip4(); let a = TcpListener::bind(addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv().unwrap(); @@ -1221,7 +1223,7 @@ mod test { let addr = next_test_ip4(); let a = TcpListener::bind(addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv().unwrap(); @@ -1230,7 +1232,7 @@ mod test { let mut s = TcpStream::connect(addr).unwrap(); let s2 = s.clone(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_err()); tx.send(()).unwrap(); @@ -1247,7 +1249,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); @@ -1280,7 +1282,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv().unwrap(); let mut amt = 0; @@ -1309,7 +1311,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); @@ -1337,7 +1339,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv().unwrap(); assert_eq!(s.write(&[0]), Ok(())); @@ -1347,7 +1349,7 @@ mod test { let mut s = a.accept().unwrap(); let s2 = s.clone(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut s2 = s2; assert_eq!(s2.read(&mut [0]), Ok(1)); tx2.send(()).unwrap(); @@ -1370,7 +1372,7 @@ mod test { let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut tcp = TcpStream::connect(addr).unwrap(); rx.recv().unwrap(); tcp.write_u8(0).unwrap(); @@ -1381,7 +1383,7 @@ mod test { let tcp = accept.accept().unwrap(); let tcp2 = tcp.clone(); let txdone3 = txdone.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut tcp2 = tcp2; tcp2.read_u8().unwrap(); txdone3.send(()).unwrap(); @@ -1389,7 +1391,7 @@ mod test { // Try to ensure that the reading clone is indeed reading for _ in 0..50 { - ::thread::Thread::yield_now(); + ::thread::yield_now(); } // clone the handle again while it's reading, then let it finish the @@ -1407,10 +1409,10 @@ mod test { let mut a = l.listen().unwrap(); let mut a2 = a.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(addr); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(addr); }); @@ -1428,19 +1430,19 @@ mod test { let (tx, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a; tx.send(a.accept()).unwrap(); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a2; tx2.send(a.accept()).unwrap(); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(addr); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _ = TcpStream::connect(addr); }); @@ -1466,7 +1468,7 @@ mod test { let mut a2 = a.clone(); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a; tx.send(a.accept()).unwrap(); }); diff --git a/src/libstd/old_io/net/udp.rs b/src/libstd/old_io/net/udp.rs index 8dc19047de0..7171198e7a4 100644 --- a/src/libstd/old_io/net/udp.rs +++ b/src/libstd/old_io/net/udp.rs @@ -186,7 +186,7 @@ mod test { use old_io::test::*; use old_io::{IoError, TimedOut, PermissionDenied, ShortWrite}; use super::*; - use thread::Thread; + use thread; // FIXME #11530 this fails on android because tests are run as root #[cfg_attr(any(windows, target_os = "android"), ignore)] @@ -206,7 +206,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { match UdpSocket::bind(client_ip) { Ok(ref mut client) => { rx1.recv().unwrap(); @@ -241,7 +241,7 @@ mod test { let client_ip = next_test_ip6(); let (tx, rx) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { match UdpSocket::bind(client_ip) { Ok(ref mut client) => { rx.recv().unwrap(); @@ -298,7 +298,7 @@ mod test { let mut sock1 = UdpSocket::bind(addr1).unwrap(); let sock2 = UdpSocket::bind(addr2).unwrap(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock2 = sock2; let mut buf = [0, 0]; assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1))); @@ -310,7 +310,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock3 = sock3; rx1.recv().unwrap(); sock3.send_to(&[1], addr2).unwrap(); @@ -331,7 +331,7 @@ mod test { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock2 = sock2; sock2.send_to(&[1], addr1).unwrap(); rx.recv().unwrap(); @@ -342,7 +342,7 @@ mod test { let sock3 = sock1.clone(); let (done, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock3 = sock3; let mut buf = [0, 0]; sock3.recv_from(&mut buf).unwrap(); @@ -366,7 +366,7 @@ mod test { let (tx, rx) = channel(); let (serv_tx, serv_rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock2 = sock2; let mut buf = [0, 1]; @@ -382,7 +382,7 @@ mod test { let (done, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut sock3 = sock3; match sock3.send_to(&[1], addr2) { Ok(..) => { let _ = tx2.send(()); } @@ -410,7 +410,7 @@ mod test { let (tx, rx) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut a = a2; assert_eq!(a.recv_from(&mut [0]), Ok((1, addr1))); assert_eq!(a.send_to(&[0], addr1), Ok(())); diff --git a/src/libstd/old_io/pipe.rs b/src/libstd/old_io/pipe.rs index 5843b1ba1b1..b7b626db034 100644 --- a/src/libstd/old_io/pipe.rs +++ b/src/libstd/old_io/pipe.rs @@ -115,7 +115,7 @@ mod test { use prelude::v1::*; use sync::mpsc::channel; - use thread::Thread; + use thread; #[test] fn partial_read() { @@ -126,7 +126,7 @@ mod test { let out = PipeStream::open(writer); let mut input = PipeStream::open(reader); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut out = out; out.write(&[10]).unwrap(); rx.recv().unwrap(); // don't close the pipe until the other read has finished diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index 195d33c41a6..ea6510c61b7 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -30,7 +30,7 @@ use sync::mpsc::{channel, Receiver}; use sys::fs::FileDesc; use sys::process::Process as ProcessImp; use sys; -use thread::Thread; +use thread; #[cfg(windows)] use hash; #[cfg(windows)] use str; @@ -703,7 +703,7 @@ impl Process { let (tx, rx) = channel(); match stream { Some(stream) => { - Thread::spawn(move || { + thread::spawn(move || { let mut stream = stream; tx.send(stream.read_to_end()).unwrap(); }); @@ -764,7 +764,7 @@ mod tests { use super::{CreatePipe}; use super::{InheritFd, Process, PleaseExitSignal, Command, ProcessOutput}; use sync::mpsc::channel; - use thread::Thread; + use thread; use time::Duration; // FIXME(#10380) these tests should not all be ignored on android. @@ -800,12 +800,12 @@ mod tests { #[cfg(all(unix, not(target_os="android")))] #[test] fn signal_reported_right() { - let p = Command::new("/bin/sh").arg("-c").arg("kill -1 $$").spawn(); + let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn(); assert!(p.is_ok()); let mut p = p.unwrap(); match p.wait().unwrap() { - process::ExitSignal(1) => {}, - result => panic!("not terminated by signal 1 (instead, {})", result), + process::ExitSignal(9) => {}, + result => panic!("not terminated by signal 9 (instead, {})", result), } } @@ -1169,14 +1169,14 @@ mod tests { fn wait_timeout2() { let (tx, rx) = channel(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut p = sleeper(); p.set_timeout(Some(10)); assert_eq!(p.wait().err().unwrap().kind, TimedOut); p.signal_kill().unwrap(); tx.send(()).unwrap(); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut p = sleeper(); p.set_timeout(Some(10)); assert_eq!(p.wait().err().unwrap().kind, TimedOut); diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs index 70cce1f7e76..e3d0232684f 100644 --- a/src/libstd/old_io/stdio.rs +++ b/src/libstd/old_io/stdio.rs @@ -530,7 +530,7 @@ mod tests { use super::*; use sync::mpsc::channel; - use thread::Thread; + use thread; #[test] fn smoke() { @@ -546,7 +546,7 @@ mod tests { let (tx, rx) = channel(); let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx)); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { set_stdout(box w); println!("hello!"); }); @@ -559,7 +559,7 @@ mod tests { let (tx, rx) = channel(); let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx)); - let _t = Thread::spawn(move || -> () { + let _t = thread::spawn(move || -> () { set_stderr(box w); panic!("my special message"); }); diff --git a/src/libstd/old_io/timer.rs b/src/libstd/old_io/timer.rs index 35f0bcb21d9..8b84e27eae1 100644 --- a/src/libstd/old_io/timer.rs +++ b/src/libstd/old_io/timer.rs @@ -224,13 +224,13 @@ fn in_ms_u64(d: Duration) -> u64 { #[cfg(test)] mod test { use super::Timer; - use thread::Thread; + use thread; use time::Duration; #[test] fn test_timer_send() { let mut timer = Timer::new().unwrap(); - Thread::spawn(move || timer.sleep(Duration::milliseconds(1))); + thread::spawn(move || timer.sleep(Duration::milliseconds(1))); } #[test] @@ -360,7 +360,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - Thread::spawn(move|| { + thread::spawn(move|| { let _ = timer_rx.recv(); }); @@ -374,7 +374,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - Thread::spawn(move|| { + thread::spawn(move|| { let _ = timer_rx.recv(); }); @@ -387,7 +387,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - Thread::spawn(move|| { + thread::spawn(move|| { let _ = timer_rx.recv(); }); diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs index 17cfe1c8297..37de2993c4d 100644 --- a/src/libstd/old_path/mod.rs +++ b/src/libstd/old_path/mod.rs @@ -59,7 +59,7 @@ //! println!("path exists: {}", path.exists()); //! ``` -#![unstable(feature = "path")] +#![unstable(feature = "old_path")] use core::marker::Sized; use ffi::CString; diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs index 6bf2a30b7b1..440d17cfd50 100644 --- a/src/libstd/old_path/posix.rs +++ b/src/libstd/old_path/posix.rs @@ -518,18 +518,18 @@ mod tests { #[test] fn test_null_byte() { - use thread::Thread; - let result = Thread::scoped(move|| { - Path::new(b"foo/bar\0") + use thread; + let result = thread::spawn(move|| { + Path::new(b"foo/bar\0"); }).join(); assert!(result.is_err()); - let result = Thread::scoped(move|| { + let result = thread::spawn(move|| { Path::new("test").set_filename(b"f\0o") }).join(); assert!(result.is_err()); - let result = Thread::scoped(move|| { + let result = thread::spawn(move|| { Path::new("test").push(b"f\0o"); }).join(); assert!(result.is_err()); diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 54c070e1b7d..07c5e10992b 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -1305,18 +1305,18 @@ mod tests { #[test] fn test_null_byte() { - use thread::Thread; - let result = Thread::scoped(move|| { - Path::new(b"foo/bar\0") + use thread; + let result = thread::spawn(move|| { + Path::new(b"foo/bar\0"); }).join(); assert!(result.is_err()); - let result = Thread::scoped(move|| { + let result = thread::spawn(move|| { Path::new("test").set_filename(b"f\0o") }).join(); assert!(result.is_err()); - let result = Thread::scoped(move || { + let result = thread::spawn(move || { Path::new("test").push(b"f\0o"); }).join(); assert!(result.is_err()); diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index e485c6a63c6..35221a7e647 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -17,7 +17,7 @@ use cell::RefCell; use old_io::IoResult; use rt::{backtrace, unwind}; use rt::util::{Stderr, Stdio}; -use thread::Thread; +use thread; // Defined in this module instead of old_io::stdio so that the unwinding thread_local! { @@ -42,7 +42,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) { } }; let mut err = Stderr; - let thread = Thread::current(); + let thread = thread::current(); let name = thread.name().unwrap_or("<unnamed>"); let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take()); match prev { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1f6d39fb1b3..1d992668900 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -107,6 +107,7 @@ use core::prelude::*; +use ascii::*; use borrow::BorrowFrom; use cmp; use iter; @@ -118,7 +119,7 @@ use fmt; use ffi::{OsStr, OsString, AsOsStr}; -use self::platform::{is_sep, is_verbatim_sep, MAIN_SEP_STR, parse_prefix, Prefix}; +use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix}; //////////////////////////////////////////////////////////////////////////////// // GENERAL NOTES @@ -139,11 +140,12 @@ use self::platform::{is_sep, is_verbatim_sep, MAIN_SEP_STR, parse_prefix, Prefix #[cfg(unix)] mod platform { + use super::Prefix; use core::prelude::*; use ffi::OsStr; #[inline] - pub fn is_sep(b: u8) -> bool { + pub fn is_sep_byte(b: u8) -> bool { b == b'/' } @@ -156,34 +158,21 @@ mod platform { None } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] - pub struct Prefix<'a>; - - impl<'a> Prefix<'a> { - #[inline] - pub fn len(&self) -> usize { 0 } - #[inline] - pub fn is_verbatim(&self) -> bool { false } - #[inline] - pub fn is_drive(&self) -> bool { false } - #[inline] - pub fn has_implicit_root(&self) -> bool { false } - } - pub const MAIN_SEP_STR: &'static str = "/"; + pub const MAIN_SEP: char = '/'; } #[cfg(windows)] mod platform { use core::prelude::*; + use ascii::*; use char::CharExt as UnicodeCharExt; - use super::{os_str_as_u8_slice, u8_slice_as_os_str}; - use ascii::*; + use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix}; use ffi::OsStr; #[inline] - pub fn is_sep(b: u8) -> bool { + pub fn is_sep_byte(b: u8) -> bool { b == b'/' || b == b'\\' } @@ -193,7 +182,7 @@ mod platform { } pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> { - use self::Prefix::*; + use super::Prefix::*; unsafe { // The unsafety here stems from converting between &OsStr and &[u8] // and back. This is safe to do because (1) we only look at ASCII @@ -224,8 +213,7 @@ mod platform { let c = path[0]; if c.is_ascii() && (c as char).is_alphabetic() { // \\?\C:\ path - let slice = u8_slice_as_os_str(&path[0..1]); - return Some(VerbatimDisk(slice)); + return Some(VerbatimDisk(c.to_ascii_uppercase())); } } let slice = &path[.. idx.unwrap_or(path.len())]; @@ -237,7 +225,7 @@ mod platform { let slice = &path[.. path.position_elem(&b'\\').unwrap_or(path.len())]; return Some(DeviceNS(u8_slice_as_os_str(slice))); } - match parse_two_comps(path, is_sep) { + match parse_two_comps(path, is_sep_byte) { Some((server, share)) if server.len() > 0 && share.len() > 0 => { // \\server\share return Some(UNC(u8_slice_as_os_str(server), @@ -249,7 +237,7 @@ mod platform { // C: let c = path[0]; if c.is_ascii() && (c as char).is_alphabetic() { - return Some(Disk(u8_slice_as_os_str(&path[0..1]))); + return Some(Disk(c.to_ascii_uppercase())); } } return None; @@ -267,99 +255,102 @@ mod platform { } } - /// Windows path prefixes. - /// - /// Windows uses a variety of path styles, including references to drive - /// volumes (like `C:`), network shared (like `\\server\share`) and - /// others. In addition, some path prefixes are "verbatim", in which case - /// `/` is *not* treated as a separator and essentially no normalization is - /// performed. - #[derive(Copy, Clone, Debug, Hash, Eq)] - pub enum Prefix<'a> { - /// Prefix `\\?\`, together with the given component immediately following it. - Verbatim(&'a OsStr), - - /// Prefix `\\?\UNC\`, with the "server" and "share" components following it. - VerbatimUNC(&'a OsStr, &'a OsStr), - - /// Prefix like `\\?\C:\`, for the given drive letter - VerbatimDisk(&'a OsStr), - - /// Prefix `\\.\`, together with the given component immediately following it. - DeviceNS(&'a OsStr), - - /// Prefix `\\server\share`, with the given "server" and "share" components. - UNC(&'a OsStr, &'a OsStr), - - /// Prefix `C:` for the given disk drive. - Disk(&'a OsStr), - } - - impl<'a> Prefix<'a> { - #[inline] - pub fn len(&self) -> usize { - use self::Prefix::*; - fn os_str_len(s: &OsStr) -> usize { - os_str_as_u8_slice(s).len() - } - match *self { - Verbatim(x) => 4 + os_str_len(x), - VerbatimUNC(x,y) => 8 + os_str_len(x) + - if os_str_len(y) > 0 { 1 + os_str_len(y) } - else { 0 }, - VerbatimDisk(_) => 6, - UNC(x,y) => 2 + os_str_len(x) + - if os_str_len(y) > 0 { 1 + os_str_len(y) } - else { 0 }, - DeviceNS(x) => 4 + os_str_len(x), - Disk(_) => 2 - } + pub const MAIN_SEP_STR: &'static str = "\\"; + pub const MAIN_SEP: char = '\\'; +} - } +//////////////////////////////////////////////////////////////////////////////// +// Windows Prefixes +//////////////////////////////////////////////////////////////////////////////// - #[inline] - pub fn is_verbatim(&self) -> bool { - use self::Prefix::*; - match *self { - Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(_, _) => true, - _ => false - } - } +/// Path prefixes (Windows only). +/// +/// Windows uses a variety of path styles, including references to drive +/// volumes (like `C:`), network shared (like `\\server\share`) and +/// others. In addition, some path prefixes are "verbatim", in which case +/// `/` is *not* treated as a separator and essentially no normalization is +/// performed. +#[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum Prefix<'a> { + /// Prefix `\\?\`, together with the given component immediately following it. + Verbatim(&'a OsStr), + + /// Prefix `\\?\UNC\`, with the "server" and "share" components following it. + VerbatimUNC(&'a OsStr, &'a OsStr), + + /// Prefix like `\\?\C:\`, for the given drive letter + VerbatimDisk(u8), + + /// Prefix `\\.\`, together with the given component immediately following it. + DeviceNS(&'a OsStr), + + /// Prefix `\\server\share`, with the given "server" and "share" components. + UNC(&'a OsStr, &'a OsStr), + + /// Prefix `C:` for the given disk drive. + Disk(u8), +} - #[inline] - pub fn is_drive(&self) -> bool { - match *self { - Prefix::Disk(_) => true, - _ => false, - } +impl<'a> Prefix<'a> { + #[inline] + fn len(&self) -> usize { + use self::Prefix::*; + fn os_str_len(s: &OsStr) -> usize { + os_str_as_u8_slice(s).len() + } + match *self { + Verbatim(x) => 4 + os_str_len(x), + VerbatimUNC(x,y) => 8 + os_str_len(x) + + if os_str_len(y) > 0 { 1 + os_str_len(y) } + else { 0 }, + VerbatimDisk(_) => 6, + UNC(x,y) => 2 + os_str_len(x) + + if os_str_len(y) > 0 { 1 + os_str_len(y) } + else { 0 }, + DeviceNS(x) => 4 + os_str_len(x), + Disk(_) => 2 } - #[inline] - pub fn has_implicit_root(&self) -> bool { - !self.is_drive() + } + + /// Determine if the prefix is verbatim, i.e. begins `\\?\`. + #[inline] + pub fn is_verbatim(&self) -> bool { + use self::Prefix::*; + match *self { + Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(_, _) => true, + _ => false } } - impl<'a> PartialEq for Prefix<'a> { - fn eq(&self, other: &Prefix<'a>) -> bool { - use self::Prefix::*; - match (*self, *other) { - (Verbatim(x), Verbatim(y)) => x == y, - (VerbatimUNC(x1, x2), VerbatimUNC(y1, y2)) => x1 == y1 && x2 == y2, - (VerbatimDisk(x), VerbatimDisk(y)) => - os_str_as_u8_slice(x).eq_ignore_ascii_case(os_str_as_u8_slice(y)), - (DeviceNS(x), DeviceNS(y)) => x == y, - (UNC(x1, x2), UNC(y1, y2)) => x1 == y1 && x2 == y2, - (Disk(x), Disk(y)) => - os_str_as_u8_slice(x).eq_ignore_ascii_case(os_str_as_u8_slice(y)), - _ => false, - } + #[inline] + fn is_drive(&self) -> bool { + match *self { + Prefix::Disk(_) => true, + _ => false, } } - pub const MAIN_SEP_STR: &'static str = "\\"; + #[inline] + fn has_implicit_root(&self) -> bool { + !self.is_drive() + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Exposed parsing helpers +//////////////////////////////////////////////////////////////////////////////// + +/// Determine whether the character is one of the permitted path +/// separators for the current platform. +pub fn is_separator(c: char) -> bool { + use ascii::*; + c.is_ascii() && is_sep_byte(c as u8) } +/// The primary sperator for the current platform +pub const MAIN_SEPARATOR: char = platform::MAIN_SEP; + //////////////////////////////////////////////////////////////////////////////// // Misc helpers //////////////////////////////////////////////////////////////////////////////// @@ -403,7 +394,7 @@ fn has_suffix(s: &[u8], prefix: Option<Prefix>) -> bool { (p.len(), p.is_verbatim()) } else { (0, false) }; if prefix_len > 0 && prefix_len == s.len() && !verbatim { return true; } - let mut splits = s[prefix_len..].split(|b| is_sep(*b)); + let mut splits = s[prefix_len..].split(|b| is_sep_byte(*b)); let last = splits.next_back().unwrap(); let more = splits.next_back().is_some(); more && last == b"" @@ -412,7 +403,7 @@ fn has_suffix(s: &[u8], prefix: Option<Prefix>) -> bool { /// Says whether the first byte after the prefix is a separator. fn has_physical_root(s: &[u8], prefix: Option<Prefix>) -> bool { let path = if let Some(p) = prefix { &s[p.len()..] } else { s }; - path.len() > 0 && is_sep(path[0]) + path.len() > 0 && is_sep_byte(path[0]) } fn parse_single_component(comp: &[u8]) -> Option<Component> { @@ -473,8 +464,16 @@ enum State { /// their role in the API. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Component<'a> { - /// A Windows path prefix, e.g. `C:` or `\server\share` - Prefix(&'a OsStr), + /// A Windows path prefix, e.g. `C:` or `\server\share`. + /// + /// Does not occur on Unix. + Prefix { + /// The prefix as an unparsed `OsStr` slice. + raw: &'a OsStr, + + /// The parsed prefix data. + parsed: Prefix<'a> + }, /// An empty component. Only used on Windows for the last component of /// verbatim paths ending with a separator (e.g. the last component of @@ -498,7 +497,7 @@ impl<'a> Component<'a> { /// Extract the underlying `OsStr` slice pub fn as_os_str(self) -> &'a OsStr { match self { - Component::Prefix(path) => path, + Component::Prefix { raw, .. } => &raw, Component::Empty => OsStr::from_str(""), Component::RootDir => OsStr::from_str(MAIN_SEP_STR), Component::CurDir => OsStr::from_str("."), @@ -568,11 +567,11 @@ impl<'a> Components<'a> { } #[inline] - fn is_sep(&self, b: u8) -> bool { + fn is_sep_byte(&self, b: u8) -> bool { if self.prefix_verbatim() { is_verbatim_sep(b) } else { - is_sep(b) + is_sep_byte(b) } } @@ -601,7 +600,7 @@ impl<'a> Components<'a> { // remove the component fn parse_next_component(&self) -> (usize, Option<Component<'a>>) { debug_assert!(self.front == State::Body); - let (extra, comp) = match self.path.iter().position(|b| self.is_sep(*b)) { + let (extra, comp) = match self.path.iter().position(|b| self.is_sep_byte(*b)) { None => (0, self.path), Some(i) => (1, &self.path[.. i]), }; @@ -613,7 +612,7 @@ impl<'a> Components<'a> { fn parse_next_component_back(&self) -> (usize, Option<Component<'a>>) { debug_assert!(self.back == State::Body); let start = self.prefix_and_root(); - let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep(*b)) { + let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep_byte(*b)) { None => (0, &self.path[start ..]), Some(i) => (1, &self.path[start + i + 1 ..]), }; @@ -680,9 +679,12 @@ impl<'a> Iterator for Components<'a> { State::Prefix if self.prefix_len() > 0 => { self.front = State::Root; debug_assert!(self.prefix_len() <= self.path.len()); - let prefix = &self.path[.. self.prefix_len()]; + let raw = &self.path[.. self.prefix_len()]; self.path = &self.path[self.prefix_len() .. ]; - return Some(Component::Prefix(unsafe { u8_slice_as_os_str(prefix) })) + return Some(Component::Prefix { + raw: unsafe { u8_slice_as_os_str(raw) }, + parsed: self.prefix.unwrap() + }) } State::Prefix => { self.front = State::Root; @@ -755,9 +757,10 @@ impl<'a> DoubleEndedIterator for Components<'a> { } State::Prefix if self.prefix_len() > 0 => { self.back = State::Done; - return Some(Component::Prefix(unsafe { - u8_slice_as_os_str(self.path) - })) + return Some(Component::Prefix { + raw: unsafe { u8_slice_as_os_str(self.path) }, + parsed: self.prefix.unwrap() + }) } State::Prefix => { self.back = State::Done; @@ -844,7 +847,7 @@ impl PathBuf { /// * if `path` has a prefix but no root, it replaces `self. pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath { // in general, a separator is needed if the rightmost byte is not a separator - let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep(*c)).unwrap_or(false); + let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false); // in the special case of `C:` on Windows, do *not* add a separator { @@ -1142,11 +1145,11 @@ impl Path { match (comp, comps.next_back()) { (Some(Component::CurDir), Some(Component::RootDir)) => None, - (Some(Component::CurDir), Some(Component::Prefix(_))) => None, + (Some(Component::CurDir), Some(Component::Prefix { .. })) => None, (Some(Component::Empty), Some(Component::RootDir)) => None, - (Some(Component::Empty), Some(Component::Prefix(_))) => None, - (Some(Component::Prefix(_)), None) => None, - (Some(Component::RootDir), Some(Component::Prefix(_))) => None, + (Some(Component::Empty), Some(Component::Prefix { .. })) => None, + (Some(Component::Prefix { .. }), None) => None, + (Some(Component::RootDir), Some(Component::Prefix { .. })) => None, _ => rest } } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d2b98ec8939..5baa095d359 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -27,7 +27,7 @@ use sys::process2::Process as ProcessImp; use sys::process2::Command as CommandImp; use sys::process2::ExitStatus as ExitStatusImp; use sys_common::{AsInner, AsInnerMut}; -use thread::Thread; +use thread; /// Representation of a running or exited child process. /// @@ -458,11 +458,11 @@ impl Child { /// the parent waits for the child to exit. pub fn wait_with_output(mut self) -> io::Result<Output> { drop(self.stdin.take()); - fn read<T: Read + Send>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> { + fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> { let (tx, rx) = channel(); match stream { Some(stream) => { - Thread::spawn(move || { + thread::spawn(move || { let mut stream = stream; let mut ret = Vec::new(); let res = stream.read_to_end(&mut ret); @@ -499,7 +499,7 @@ mod tests { use str; use super::{Child, Command, Output, ExitStatus, Stdio}; use sync::mpsc::channel; - use thread::Thread; + use thread; use time::Duration; // FIXME(#10380) these tests should not all be ignored on android. @@ -537,12 +537,12 @@ mod tests { fn signal_reported_right() { use os::unix::ExitStatusExt; - let p = Command::new("/bin/sh").arg("-c").arg("kill -1 $$").spawn(); + let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn(); assert!(p.is_ok()); let mut p = p.unwrap(); match p.wait().unwrap().signal() { - Some(1) => {}, - result => panic!("not terminated by signal 1 (instead, {:?})", result), + Some(9) => {}, + result => panic!("not terminated by signal 9 (instead, {:?})", result), } } diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 535af08c96c..0feacf5581c 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -360,7 +360,7 @@ mod test { use sync::mpsc::channel; use rand::Rng; use super::OsRng; - use thread::Thread; + use thread; #[test] fn test_os_rng() { @@ -381,23 +381,23 @@ mod test { let (tx, rx) = channel(); txs.push(tx); - Thread::spawn(move|| { + thread::spawn(move|| { // wait until all the tasks are ready to go. rx.recv().unwrap(); // deschedule to attempt to interleave things as much // as possible (XXX: is this a good test?) let mut r = OsRng::new().unwrap(); - Thread::yield_now(); + thread::yield_now(); let mut v = [0u8; 1000]; for _ in 0u..100 { r.next_u32(); - Thread::yield_now(); + thread::yield_now(); r.next_u64(); - Thread::yield_now(); + thread::yield_now(); r.fill_bytes(&mut v); - Thread::yield_now(); + thread::yield_now(); } }); } diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs index 3f15cf71ec3..72486fc55d4 100644 --- a/src/libstd/rt/at_exit_imp.rs +++ b/src/libstd/rt/at_exit_imp.rs @@ -20,7 +20,7 @@ use mem; use thunk::Thunk; use sys_common::mutex::{Mutex, MUTEX_INIT}; -type Queue = Vec<Thunk>; +type Queue = Vec<Thunk<'static>>; // NB these are specifically not types from `std::sync` as they currently rely // on poisoning and this module needs to operate at a lower level than requiring @@ -65,7 +65,7 @@ pub fn cleanup() { } } -pub fn push(f: Thunk) { +pub fn push(f: Thunk<'static>) { unsafe { LOCK.lock(); init(); diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 00088d6d99a..42cca73e5e2 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -148,7 +148,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { /// /// It is forbidden for procedures to register more `at_exit` handlers when they /// are running, and doing so will lead to a process abort. -pub fn at_exit<F:FnOnce()+Send>(f: F) { +pub fn at_exit<F:FnOnce()+Send+'static>(f: F) { at_exit_imp::push(Thunk::new(f)); } diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index c9bbea27e4a..1f5eb3af695 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -74,7 +74,7 @@ use rt::libunwind as uw; struct Exception { uwe: uw::_Unwind_Exception, - cause: Option<Box<Any + Send>>, + cause: Option<Box<Any + Send + 'static>>, } pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint); @@ -161,7 +161,7 @@ pub fn panicking() -> bool { #[inline(never)] #[no_mangle] #[allow(private_no_mangle_fns)] -fn rust_panic(cause: Box<Any + Send>) -> ! { +fn rust_panic(cause: Box<Any + Send + 'static>) -> ! { rtdebug!("begin_unwind()"); unsafe { diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index d445c299028..a304f1f844d 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -149,7 +149,7 @@ pub fn abort(args: fmt::Arguments) -> ! { } pub unsafe fn report_overflow() { - use thread::Thread; + use thread; // See the message below for why this is not emitted to the // ^ Where did the message below go? @@ -159,5 +159,5 @@ pub unsafe fn report_overflow() { // and the FFI call needs 2MB of stack when we just ran out. rterrln!("\nthread '{}' has overflowed its stack", - Thread::current().name().unwrap_or("<unknown>")); + thread::current().name().unwrap_or("<unknown>")); } diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index cca376f7b6d..fc781eb4bec 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -15,14 +15,14 @@ use sync::{Mutex, Condvar}; /// /// ```rust /// use std::sync::{Arc, Barrier}; -/// use std::thread::Thread; +/// use std::thread; /// /// let barrier = Arc::new(Barrier::new(10)); /// for _ in 0u..10 { /// let c = barrier.clone(); /// // The same messages will be printed together. /// // You will NOT see any interleaving. -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// println!("before wait"); /// c.wait(); /// println!("after wait"); @@ -111,7 +111,7 @@ mod tests { use sync::{Arc, Barrier}; use sync::mpsc::{channel, TryRecvError}; - use thread::Thread; + use thread; #[test] fn test_barrier() { @@ -123,7 +123,7 @@ mod tests { for _ in 0u..N - 1 { let c = barrier.clone(); let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(c.wait().is_leader()).unwrap(); }); } diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index d4d722cab3d..52561d482c3 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -38,13 +38,13 @@ use sync::{mutex, MutexGuard, PoisonError}; /// /// ``` /// use std::sync::{Arc, Mutex, Condvar}; -/// use std::thread::Thread; +/// use std::thread; /// /// let pair = Arc::new((Mutex::new(false), Condvar::new())); /// let pair2 = pair.clone(); /// /// // Inside of our lock, spawn a new thread, and then wait for it to start -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// let &(ref lock, ref cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; @@ -353,7 +353,7 @@ mod tests { use sync::mpsc::channel; use sync::{StaticMutex, MUTEX_INIT, Condvar, Mutex, Arc}; use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; - use thread::Thread; + use thread; use time::Duration; #[test] @@ -377,7 +377,7 @@ mod tests { static M: StaticMutex = MUTEX_INIT; let g = M.lock().unwrap(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _g = M.lock().unwrap(); C.notify_one(); }); @@ -395,7 +395,7 @@ mod tests { for _ in 0..N { let data = data.clone(); let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { let &(ref lock, ref cond) = &*data; let mut cnt = lock.lock().unwrap(); *cnt += 1; @@ -431,7 +431,7 @@ mod tests { let (g, _no_timeout) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap(); // spurious wakeups mean this isn't necessarily true // assert!(!no_timeout); - let _t = Thread::spawn(move || { + let _t = thread::spawn(move || { let _g = M.lock().unwrap(); C.notify_one(); }); @@ -452,7 +452,7 @@ mod tests { assert!(!success); let (tx, rx) = channel(); - let _t = Thread::scoped(move || { + let _t = thread::spawn(move || { rx.recv().unwrap(); let g = M.lock().unwrap(); S.store(1, Ordering::SeqCst); @@ -492,7 +492,7 @@ mod tests { static C: StaticCondvar = CONDVAR_INIT; let mut g = M1.lock().unwrap(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _g = M1.lock().unwrap(); C.notify_one(); }); diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index a230e35dac8..d60e2738808 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -38,7 +38,7 @@ use core::mem::replace; use self::FutureState::*; use sync::mpsc::{Receiver, channel}; use thunk::{Thunk}; -use thread::Thread; +use thread; /// A type encapsulating the result of a computation which may not be complete pub struct Future<A> { @@ -46,7 +46,7 @@ pub struct Future<A> { } enum FutureState<A> { - Pending(Thunk<(),A>), + Pending(Thunk<'static,(),A>), Evaluating, Forced(A) } @@ -103,7 +103,7 @@ impl<A> Future<A> { } pub fn from_fn<F>(f: F) -> Future<A> - where F : FnOnce() -> A, F : Send + where F : FnOnce() -> A, F : Send + 'static { /*! * Create a future from a function. @@ -117,7 +117,7 @@ impl<A> Future<A> { } } -impl<A:Send> Future<A> { +impl<A:Send+'static> Future<A> { pub fn from_receiver(rx: Receiver<A>) -> Future<A> { /*! * Create a future from a port @@ -132,7 +132,7 @@ impl<A:Send> Future<A> { } pub fn spawn<F>(blk: F) -> Future<A> - where F : FnOnce() -> A, F : Send + where F : FnOnce() -> A, F : Send + 'static { /*! * Create a future from a unique closure. @@ -143,7 +143,7 @@ impl<A:Send> Future<A> { let (tx, rx) = channel(); - Thread::spawn(move || { + thread::spawn(move || { // Don't panic if the other end has hung up let _ = tx.send(blk()); }); @@ -157,7 +157,7 @@ mod test { use prelude::v1::*; use sync::mpsc::channel; use sync::Future; - use thread::Thread; + use thread; #[test] fn test_from_value() { @@ -215,7 +215,7 @@ mod test { let expected = "schlorf"; let (tx, rx) = channel(); let f = Future::spawn(move|| { expected }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut f = f; tx.send(f.get()).unwrap(); }); diff --git a/src/libstd/sync/mpsc/blocking.rs b/src/libstd/sync/mpsc/blocking.rs index 61ffb532d36..69b1e242b15 100644 --- a/src/libstd/sync/mpsc/blocking.rs +++ b/src/libstd/sync/mpsc/blocking.rs @@ -10,7 +10,7 @@ //! Generic support for building blocking abstractions. -use thread::Thread; +use thread::{self, Thread}; use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; use sync::Arc; use marker::{Sync, Send}; @@ -40,7 +40,7 @@ impl !Sync for WaitToken {} pub fn tokens() -> (WaitToken, SignalToken) { let inner = Arc::new(Inner { - thread: Thread::current(), + thread: thread::current(), woken: ATOMIC_BOOL_INIT, }); let wait_token = WaitToken { @@ -80,7 +80,7 @@ impl SignalToken { impl WaitToken { pub fn wait(self) { while !self.inner.woken.load(Ordering::SeqCst) { - Thread::park() + thread::park() } } } diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index d783acd57ac..410d3c0ecd5 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -53,12 +53,12 @@ //! Simple usage: //! //! ``` -//! use std::thread::Thread; +//! use std::thread; //! use std::sync::mpsc::channel; //! //! // Create a simple streaming channel //! let (tx, rx) = channel(); -//! Thread::spawn(move|| { +//! thread::spawn(move|| { //! tx.send(10).unwrap(); //! }); //! assert_eq!(rx.recv().unwrap(), 10); @@ -67,7 +67,7 @@ //! Shared usage: //! //! ``` -//! use std::thread::Thread; +//! use std::thread; //! use std::sync::mpsc::channel; //! //! // Create a shared channel that can be sent along from many threads @@ -76,7 +76,7 @@ //! let (tx, rx) = channel(); //! for i in 0..10 { //! let tx = tx.clone(); -//! Thread::spawn(move|| { +//! thread::spawn(move|| { //! tx.send(i).unwrap(); //! }); //! } @@ -102,11 +102,11 @@ //! Synchronous channels: //! //! ``` -//! use std::thread::Thread; +//! use std::thread; //! use std::sync::mpsc::sync_channel; //! //! let (tx, rx) = sync_channel::<int>(0); -//! Thread::spawn(move|| { +//! thread::spawn(move|| { //! // This will wait for the parent task to start receiving //! tx.send(53).unwrap(); //! }); @@ -345,7 +345,7 @@ pub struct Receiver<T> { // The receiver port can be sent from place to place, so long as it // is not used to receive non-sendable things. -unsafe impl<T:Send> Send for Receiver<T> { } +unsafe impl<T: Send + 'static> Send for Receiver<T> { } /// An iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be @@ -364,7 +364,7 @@ pub struct Sender<T> { // The send port can be sent from place to place, so long as it // is not used to send non-sendable things. -unsafe impl<T:Send> Send for Sender<T> { } +unsafe impl<T: Send + 'static> 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. @@ -373,7 +373,7 @@ pub struct SyncSender<T> { inner: Arc<UnsafeCell<sync::Packet<T>>>, } -unsafe impl<T:Send> Send for SyncSender<T> {} +unsafe impl<T: Send + 'static> Send for SyncSender<T> {} impl<T> !Sync for SyncSender<T> {} @@ -467,14 +467,14 @@ impl<T> UnsafeFlavor<T> for Receiver<T> { /// /// ``` /// use std::sync::mpsc::channel; -/// use std::thread::Thread; +/// use std::thread; /// /// // tx is is the sending half (tx for transmission), and rx is the receiving /// // half (rx for receiving). /// let (tx, rx) = channel(); /// /// // Spawn off an expensive computation -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// # fn expensive_computation() {} /// tx.send(expensive_computation()).unwrap(); /// }); @@ -485,7 +485,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> { /// println!("{:?}", rx.recv().unwrap()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) { +pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) { let a = Arc::new(UnsafeCell::new(oneshot::Packet::new())); (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a))) } @@ -509,14 +509,14 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) { /// /// ``` /// use std::sync::mpsc::sync_channel; -/// use std::thread::Thread; +/// use std::thread; /// /// let (tx, rx) = sync_channel(1); /// /// // this returns immediately /// tx.send(1).unwrap(); /// -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// // this will block until the previous message has been received /// tx.send(2).unwrap(); /// }); @@ -525,7 +525,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) { /// assert_eq!(rx.recv().unwrap(), 2); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) { +pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<T>) { let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound))); (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a))) } @@ -534,7 +534,7 @@ pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) { // Sender //////////////////////////////////////////////////////////////////////////////// -impl<T: Send> Sender<T> { +impl<T: Send + 'static> Sender<T> { fn new(inner: Flavor<T>) -> Sender<T> { Sender { inner: UnsafeCell::new(inner), @@ -616,7 +616,7 @@ impl<T: Send> Sender<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Clone for Sender<T> { +impl<T: Send + 'static> Clone for Sender<T> { fn clone(&self) -> Sender<T> { let (packet, sleeper, guard) = match *unsafe { self.inner() } { Flavor::Oneshot(ref p) => { @@ -662,7 +662,7 @@ impl<T: Send> Clone for Sender<T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Drop for Sender<T> { +impl<T: Send + 'static> Drop for Sender<T> { fn drop(&mut self) { match *unsafe { self.inner_mut() } { Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); }, @@ -677,7 +677,7 @@ impl<T: Send> Drop for Sender<T> { // SyncSender //////////////////////////////////////////////////////////////////////////////// -impl<T: Send> SyncSender<T> { +impl<T: Send + 'static> SyncSender<T> { fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> { SyncSender { inner: inner } } @@ -717,7 +717,7 @@ impl<T: Send> SyncSender<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Clone for SyncSender<T> { +impl<T: Send + 'static> Clone for SyncSender<T> { fn clone(&self) -> SyncSender<T> { unsafe { (*self.inner.get()).clone_chan(); } return SyncSender::new(self.inner.clone()); @@ -726,7 +726,7 @@ impl<T: Send> Clone for SyncSender<T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Drop for SyncSender<T> { +impl<T: Send + 'static> Drop for SyncSender<T> { fn drop(&mut self) { unsafe { (*self.inner.get()).drop_chan(); } } @@ -736,7 +736,7 @@ impl<T: Send> Drop for SyncSender<T> { // Receiver //////////////////////////////////////////////////////////////////////////////// -impl<T: Send> Receiver<T> { +impl<T: Send + 'static> Receiver<T> { fn new(inner: Flavor<T>) -> Receiver<T> { Receiver { inner: UnsafeCell::new(inner) } } @@ -855,7 +855,7 @@ impl<T: Send> Receiver<T> { } } -impl<T: Send> select::Packet for Receiver<T> { +impl<T: Send + 'static> select::Packet for Receiver<T> { fn can_recv(&self) -> bool { loop { let new_port = match *unsafe { self.inner() } { @@ -942,7 +942,7 @@ impl<T: Send> select::Packet for Receiver<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: Send> Iterator for Iter<'a, T> { +impl<'a, T: Send + 'static> Iterator for Iter<'a, T> { type Item = T; fn next(&mut self) -> Option<T> { self.rx.recv().ok() } @@ -950,7 +950,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Drop for Receiver<T> { +impl<T: Send + 'static> Drop for Receiver<T> { fn drop(&mut self) { match *unsafe { self.inner_mut() } { Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); }, @@ -1026,7 +1026,7 @@ mod test { use std::env; use super::*; - use thread::Thread; + use thread; pub fn stress_factor() -> uint { match env::var("RUST_TEST_STRESS") { @@ -1069,7 +1069,7 @@ mod test { #[test] fn smoke_threads() { let (tx, rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(1).unwrap(); }); assert_eq!(rx.recv().unwrap(), 1); @@ -1101,7 +1101,7 @@ mod test { #[test] fn port_gone_concurrent() { let (tx, rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); }); while tx.send(1).is_ok() {} @@ -1111,7 +1111,7 @@ mod test { fn port_gone_concurrent_shared() { let (tx, rx) = channel::<int>(); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); }); while tx.send(1).is_ok() && tx2.send(1).is_ok() {} @@ -1136,7 +1136,7 @@ mod test { #[test] fn chan_gone_concurrent() { let (tx, rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(1).unwrap(); tx.send(1).unwrap(); }); @@ -1146,7 +1146,7 @@ mod test { #[test] fn stress() { let (tx, rx) = channel::<int>(); - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { for _ in 0u..10000 { tx.send(1).unwrap(); } }); for _ in 0u..10000 { @@ -1161,7 +1161,7 @@ mod test { static NTHREADS: uint = 8; let (tx, rx) = channel::<int>(); - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { for _ in 0..AMT * NTHREADS { assert_eq!(rx.recv().unwrap(), 1); } @@ -1173,7 +1173,7 @@ mod test { for _ in 0..NTHREADS { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { for _ in 0..AMT { tx.send(1).unwrap(); } }); } @@ -1185,14 +1185,14 @@ mod test { fn send_from_outside_runtime() { let (tx1, rx1) = channel::<()>(); let (tx2, rx2) = channel::<int>(); - let t1 = Thread::scoped(move|| { + let t1 = thread::spawn(move|| { tx1.send(()).unwrap(); for _ in 0..40 { assert_eq!(rx2.recv().unwrap(), 1); } }); rx1.recv().unwrap(); - let t2 = Thread::scoped(move|| { + let t2 = thread::spawn(move|| { for _ in 0..40 { tx2.send(1).unwrap(); } @@ -1204,7 +1204,7 @@ mod test { #[test] fn recv_from_outside_runtime() { let (tx, rx) = channel::<int>(); - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { for _ in 0..40 { assert_eq!(rx.recv().unwrap(), 1); } @@ -1219,11 +1219,11 @@ mod test { fn no_runtime() { let (tx1, rx1) = channel::<int>(); let (tx2, rx2) = channel::<int>(); - let t1 = Thread::scoped(move|| { + let t1 = thread::spawn(move|| { assert_eq!(rx1.recv().unwrap(), 1); tx2.send(2).unwrap(); }); - let t2 = Thread::scoped(move|| { + let t2 = thread::spawn(move|| { tx1.send(1).unwrap(); assert_eq!(rx2.recv().unwrap(), 2); }); @@ -1256,7 +1256,7 @@ mod test { #[test] fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = Thread::scoped(move|| { + let res = thread::spawn(move|| { let (tx, rx) = channel::<int>(); drop(tx); rx.recv().unwrap(); @@ -1325,7 +1325,7 @@ mod test { #[test] fn oneshot_multi_task_recv_then_send() { let (tx, rx) = channel::<Box<int>>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { assert!(rx.recv().unwrap() == box 10); }); @@ -1335,10 +1335,10 @@ mod test { #[test] fn oneshot_multi_task_recv_then_close() { let (tx, rx) = channel::<Box<int>>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(tx); }); - let res = Thread::scoped(move|| { + let res = thread::spawn(move|| { assert!(rx.recv().unwrap() == box 10); }).join(); assert!(res.is_err()); @@ -1348,7 +1348,7 @@ mod test { fn oneshot_multi_thread_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(rx); }); drop(tx); @@ -1359,10 +1359,10 @@ mod test { fn oneshot_multi_thread_send_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(rx); }); - let _ = Thread::scoped(move|| { + let _ = thread::spawn(move|| { tx.send(1).unwrap(); }).join(); } @@ -1372,14 +1372,14 @@ mod test { fn oneshot_multi_thread_recv_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = channel::<int>(); - Thread::spawn(move|| { - let res = Thread::scoped(move|| { + thread::spawn(move|| { + let res = thread::spawn(move|| { rx.recv().unwrap(); }).join(); assert!(res.is_err()); }); - let _t = Thread::spawn(move|| { - Thread::spawn(move|| { + let _t = thread::spawn(move|| { + thread::spawn(move|| { drop(tx); }); }); @@ -1390,7 +1390,7 @@ mod test { fn oneshot_multi_thread_send_recv_stress() { for _ in 0..stress_factor() { let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(box 10).unwrap(); }); assert!(rx.recv().unwrap() == box 10); @@ -1408,7 +1408,7 @@ mod test { fn send(tx: Sender<Box<int>>, i: int) { if i == 10 { return } - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(box i).unwrap(); send(tx, i + 1); }); @@ -1417,7 +1417,7 @@ mod test { fn recv(rx: Receiver<Box<int>>, i: int) { if i == 10 { return } - Thread::spawn(move|| { + thread::spawn(move|| { assert!(rx.recv().unwrap() == box i); recv(rx, i + 1); }); @@ -1439,7 +1439,7 @@ mod test { let total = stress_factor() + 100; for _ in 0..total { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(()).unwrap(); }); } @@ -1454,7 +1454,7 @@ mod test { let (tx, rx) = channel::<int>(); let (total_tx, total_rx) = channel::<int>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acc = 0; for x in rx.iter() { acc += x; @@ -1474,7 +1474,7 @@ mod test { let (tx, rx) = channel::<int>(); let (count_tx, count_rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut count = 0; for x in rx.iter() { if count >= 3 { @@ -1499,7 +1499,7 @@ mod test { let (tx1, rx1) = channel::<int>(); let (tx2, rx2) = channel::<()>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx2.recv().unwrap(); tx1.send(1).unwrap(); tx3.send(()).unwrap(); @@ -1524,13 +1524,13 @@ mod test { fn destroy_upgraded_shared_port_when_sender_still_active() { let (tx, rx) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); // wait on a oneshot drop(rx); // destroy a shared tx2.send(()).unwrap(); }); // make sure the other task has gone to sleep - for _ in 0u..5000 { Thread::yield_now(); } + for _ in 0u..5000 { thread::yield_now(); } // upgrade to a shared chan and send a message let t = tx.clone(); @@ -1547,7 +1547,7 @@ mod sync_tests { use prelude::v1::*; use std::env; - use thread::Thread; + use thread; use super::*; pub fn stress_factor() -> uint { @@ -1583,7 +1583,7 @@ mod sync_tests { #[test] fn smoke_threads() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(1).unwrap(); }); assert_eq!(rx.recv().unwrap(), 1); @@ -1608,7 +1608,7 @@ mod sync_tests { #[test] fn port_gone_concurrent() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); }); while tx.send(1).is_ok() {} @@ -1618,7 +1618,7 @@ mod sync_tests { fn port_gone_concurrent_shared() { let (tx, rx) = sync_channel::<int>(0); let tx2 = tx.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); }); while tx.send(1).is_ok() && tx2.send(1).is_ok() {} @@ -1643,7 +1643,7 @@ mod sync_tests { #[test] fn chan_gone_concurrent() { let (tx, rx) = sync_channel::<int>(0); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(1).unwrap(); tx.send(1).unwrap(); }); @@ -1653,7 +1653,7 @@ mod sync_tests { #[test] fn stress() { let (tx, rx) = sync_channel::<int>(0); - Thread::spawn(move|| { + thread::spawn(move|| { for _ in 0u..10000 { tx.send(1).unwrap(); } }); for _ in 0u..10000 { @@ -1668,7 +1668,7 @@ mod sync_tests { let (tx, rx) = sync_channel::<int>(0); let (dtx, drx) = sync_channel::<()>(0); - Thread::spawn(move|| { + thread::spawn(move|| { for _ in 0..AMT * NTHREADS { assert_eq!(rx.recv().unwrap(), 1); } @@ -1681,7 +1681,7 @@ mod sync_tests { for _ in 0..NTHREADS { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { for _ in 0..AMT { tx.send(1).unwrap(); } }); } @@ -1714,7 +1714,7 @@ mod sync_tests { #[test] fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = Thread::scoped(move|| { + let res = thread::spawn(move|| { let (tx, rx) = sync_channel::<int>(0); drop(tx); rx.recv().unwrap(); @@ -1789,7 +1789,7 @@ mod sync_tests { #[test] fn oneshot_multi_task_recv_then_send() { let (tx, rx) = sync_channel::<Box<int>>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { assert!(rx.recv().unwrap() == box 10); }); @@ -1799,10 +1799,10 @@ mod sync_tests { #[test] fn oneshot_multi_task_recv_then_close() { let (tx, rx) = sync_channel::<Box<int>>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(tx); }); - let res = Thread::scoped(move|| { + let res = thread::spawn(move|| { assert!(rx.recv().unwrap() == box 10); }).join(); assert!(res.is_err()); @@ -1812,7 +1812,7 @@ mod sync_tests { fn oneshot_multi_thread_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(rx); }); drop(tx); @@ -1823,10 +1823,10 @@ mod sync_tests { fn oneshot_multi_thread_send_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { drop(rx); }); - let _ = Thread::scoped(move || { + let _ = thread::spawn(move || { tx.send(1).unwrap(); }).join(); } @@ -1836,14 +1836,14 @@ mod sync_tests { fn oneshot_multi_thread_recv_close_stress() { for _ in 0..stress_factor() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { - let res = Thread::scoped(move|| { + let _t = thread::spawn(move|| { + let res = thread::spawn(move|| { rx.recv().unwrap(); }).join(); assert!(res.is_err()); }); - let _t = Thread::spawn(move|| { - Thread::spawn(move|| { + let _t = thread::spawn(move|| { + thread::spawn(move|| { drop(tx); }); }); @@ -1854,7 +1854,7 @@ mod sync_tests { fn oneshot_multi_thread_send_recv_stress() { for _ in 0..stress_factor() { let (tx, rx) = sync_channel::<Box<int>>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { tx.send(box 10).unwrap(); }); assert!(rx.recv().unwrap() == box 10); @@ -1872,7 +1872,7 @@ mod sync_tests { fn send(tx: SyncSender<Box<int>>, i: int) { if i == 10 { return } - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(box i).unwrap(); send(tx, i + 1); }); @@ -1881,7 +1881,7 @@ mod sync_tests { fn recv(rx: Receiver<Box<int>>, i: int) { if i == 10 { return } - Thread::spawn(move|| { + thread::spawn(move|| { assert!(rx.recv().unwrap() == box i); recv(rx, i + 1); }); @@ -1903,7 +1903,7 @@ mod sync_tests { let total = stress_factor() + 100; for _ in 0..total { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(()).unwrap(); }); } @@ -1918,7 +1918,7 @@ mod sync_tests { let (tx, rx) = sync_channel::<int>(0); let (total_tx, total_rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut acc = 0; for x in rx.iter() { acc += x; @@ -1938,7 +1938,7 @@ mod sync_tests { let (tx, rx) = sync_channel::<int>(0); let (count_tx, count_rx) = sync_channel(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let mut count = 0; for x in rx.iter() { if count >= 3 { @@ -1963,7 +1963,7 @@ mod sync_tests { let (tx1, rx1) = sync_channel::<int>(1); let (tx2, rx2) = sync_channel::<()>(1); let (tx3, rx3) = sync_channel::<()>(1); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx2.recv().unwrap(); tx1.send(1).unwrap(); tx3.send(()).unwrap(); @@ -1988,13 +1988,13 @@ mod sync_tests { fn destroy_upgraded_shared_port_when_sender_still_active() { let (tx, rx) = sync_channel::<()>(0); let (tx2, rx2) = sync_channel::<()>(0); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx.recv().unwrap(); // wait on a oneshot drop(rx); // destroy a shared tx2.send(()).unwrap(); }); // make sure the other task has gone to sleep - for _ in 0u..5000 { Thread::yield_now(); } + for _ in 0u..5000 { thread::yield_now(); } // upgrade to a shared chan and send a message let t = tx.clone(); @@ -2008,14 +2008,14 @@ mod sync_tests { #[test] fn send1() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { rx.recv().unwrap(); }); + let _t = thread::spawn(move|| { rx.recv().unwrap(); }); assert_eq!(tx.send(1), Ok(())); } #[test] fn send2() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { drop(rx); }); + let _t = thread::spawn(move|| { drop(rx); }); assert!(tx.send(1).is_err()); } @@ -2023,7 +2023,7 @@ mod sync_tests { fn send3() { let (tx, rx) = sync_channel::<int>(1); assert_eq!(tx.send(1), Ok(())); - let _t =Thread::spawn(move|| { drop(rx); }); + let _t =thread::spawn(move|| { drop(rx); }); assert!(tx.send(1).is_err()); } @@ -2033,11 +2033,11 @@ mod sync_tests { let tx2 = tx.clone(); let (done, donerx) = channel(); let done2 = done.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { assert!(tx.send(1).is_err()); done.send(()).unwrap(); }); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { assert!(tx2.send(2).is_err()); done2.send(()).unwrap(); }); @@ -2073,7 +2073,7 @@ mod sync_tests { let (tx1, rx1) = sync_channel::<()>(3); let (tx2, rx2) = sync_channel::<()>(3); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx1.recv().unwrap(); tx2.try_send(()).unwrap(); }); diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index 3980d2a1fef..0a4ff8769ab 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -78,7 +78,7 @@ pub struct Queue<T> { } unsafe impl<T:Send> Send for Queue<T> { } -unsafe impl<T:Send> Sync for Queue<T> { } +unsafe impl<T: Send + 'static> Sync for Queue<T> { } impl<T> Node<T> { unsafe fn new(v: Option<T>) -> *mut Node<T> { @@ -89,7 +89,7 @@ impl<T> Node<T> { } } -impl<T: Send> Queue<T> { +impl<T: Send + 'static> Queue<T> { /// Creates a new queue that is safe to share among multiple producers and /// one consumer. pub fn new() -> Queue<T> { @@ -140,7 +140,7 @@ impl<T: Send> Queue<T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Drop for Queue<T> { +impl<T: Send + 'static> Drop for Queue<T> { fn drop(&mut self) { unsafe { let mut cur = *self.tail.get(); @@ -160,7 +160,7 @@ mod tests { use sync::mpsc::channel; use super::{Queue, Data, Empty, Inconsistent}; use sync::Arc; - use thread::Thread; + use thread; #[test] fn test_full() { @@ -184,7 +184,7 @@ mod tests { for _ in 0..nthreads { let tx = tx.clone(); let q = q.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { for i in 0..nmsgs { q.push(i); } diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs index eb45681fa62..55b2caf7c6d 100644 --- a/src/libstd/sync/mpsc/oneshot.rs +++ b/src/libstd/sync/mpsc/oneshot.rs @@ -88,7 +88,7 @@ enum MyUpgrade<T> { GoUp(Receiver<T>), } -impl<T: Send> Packet<T> { +impl<T: Send + 'static> Packet<T> { pub fn new() -> Packet<T> { Packet { data: None, @@ -368,7 +368,7 @@ impl<T: Send> Packet<T> { } #[unsafe_destructor] -impl<T: Send> Drop for Packet<T> { +impl<T: Send + 'static> Drop for Packet<T> { fn drop(&mut self) { assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED); } diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 87b2fe8f100..4756ef612f9 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -134,7 +134,7 @@ impl Select { /// Creates a new handle into this receiver set for a new receiver. Note /// that this does *not* add the receiver to the receiver set, for that you /// must call the `add` method on the handle itself. - pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> { + pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> { let id = self.next_id.get(); self.next_id.set(id + 1); Handle { @@ -251,7 +251,7 @@ impl Select { fn iter(&self) -> Packets { Packets { cur: self.head } } } -impl<'rx, T: Send> Handle<'rx, T> { +impl<'rx, T: Send + 'static> Handle<'rx, T> { /// Retrieve the id of this handle. #[inline] pub fn id(&self) -> uint { self.id } @@ -322,7 +322,7 @@ impl Drop for Select { } #[unsafe_destructor] -impl<'rx, T: Send> Drop for Handle<'rx, T> { +impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> { fn drop(&mut self) { unsafe { self.remove() } } @@ -347,7 +347,7 @@ impl Iterator for Packets { mod test { use prelude::v1::*; - use thread::Thread; + use thread; use sync::mpsc::*; // Don't use the libstd version so we can pull in the right Select structure @@ -427,11 +427,11 @@ mod test { let (_tx2, rx2) = channel::<int>(); let (tx3, rx3) = channel::<int>(); - let _t = Thread::spawn(move|| { - for _ in 0u..20 { Thread::yield_now(); } + let _t = thread::spawn(move|| { + for _ in 0u..20 { thread::yield_now(); } tx1.send(1).unwrap(); rx3.recv().unwrap(); - for _ in 0u..20 { Thread::yield_now(); } + for _ in 0u..20 { thread::yield_now(); } }); select! { @@ -451,8 +451,8 @@ mod test { let (tx2, rx2) = channel::<int>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { - for _ in 0u..20 { Thread::yield_now(); } + let _t = thread::spawn(move|| { + for _ in 0u..20 { thread::yield_now(); } tx1.send(1).unwrap(); tx2.send(2).unwrap(); rx3.recv().unwrap(); @@ -478,7 +478,7 @@ mod test { let (tx2, rx2) = channel::<int>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { for i in 0..AMT { if i % 2 == 0 { tx1.send(i).unwrap(); @@ -504,7 +504,7 @@ mod test { let (_tx2, rx2) = channel::<int>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx3.recv().unwrap(); tx1.clone(); assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty)); @@ -526,7 +526,7 @@ mod test { let (_tx2, rx2) = channel::<int>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { rx3.recv().unwrap(); tx1.clone(); assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty)); @@ -547,7 +547,7 @@ mod test { let (tx1, rx1) = channel::<()>(); let (tx2, rx2) = channel::<()>(); let (tx3, rx3) = channel::<()>(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let s = Select::new(); let mut h1 = s.handle(&rx1); let mut h2 = s.handle(&rx2); @@ -557,7 +557,7 @@ mod test { tx3.send(()).unwrap(); }); - for _ in 0u..1000 { Thread::yield_now(); } + for _ in 0u..1000 { thread::yield_now(); } drop(tx1.clone()); tx2.send(()).unwrap(); rx3.recv().unwrap(); @@ -663,14 +663,14 @@ mod test { fn oneshot_data_waiting() { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { select! { _n = rx1.recv() => {} } tx2.send(()).unwrap(); }); - for _ in 0u..100 { Thread::yield_now() } + for _ in 0u..100 { thread::yield_now() } tx1.send(()).unwrap(); rx2.recv().unwrap(); } @@ -683,14 +683,14 @@ mod test { tx1.send(()).unwrap(); rx1.recv().unwrap(); rx1.recv().unwrap(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { select! { _n = rx1.recv() => {} } tx2.send(()).unwrap(); }); - for _ in 0u..100 { Thread::yield_now() } + for _ in 0u..100 { thread::yield_now() } tx1.send(()).unwrap(); rx2.recv().unwrap(); } @@ -702,14 +702,14 @@ mod test { drop(tx1.clone()); tx1.send(()).unwrap(); rx1.recv().unwrap(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { select! { _n = rx1.recv() => {} } tx2.send(()).unwrap(); }); - for _ in 0u..100 { Thread::yield_now() } + for _ in 0u..100 { thread::yield_now() } tx1.send(()).unwrap(); rx2.recv().unwrap(); } @@ -726,8 +726,8 @@ mod test { #[test] fn sync2() { let (tx, rx) = sync_channel::<int>(0); - let _t = Thread::spawn(move|| { - for _ in 0u..100 { Thread::yield_now() } + let _t = thread::spawn(move|| { + for _ in 0u..100 { thread::yield_now() } tx.send(1).unwrap(); }); select! { @@ -739,8 +739,8 @@ mod test { fn sync3() { let (tx1, rx1) = sync_channel::<int>(0); let (tx2, rx2): (Sender<int>, Receiver<int>) = channel(); - let _t = Thread::spawn(move|| { tx1.send(1).unwrap(); }); - let _t = Thread::spawn(move|| { tx2.send(2).unwrap(); }); + let _t = thread::spawn(move|| { tx1.send(1).unwrap(); }); + let _t = thread::spawn(move|| { tx2.send(2).unwrap(); }); select! { n = rx1.recv() => { let n = n.unwrap(); diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs index 6c31fb92591..bc9c73585c2 100644 --- a/src/libstd/sync/mpsc/shared.rs +++ b/src/libstd/sync/mpsc/shared.rs @@ -31,7 +31,7 @@ use sync::mpsc::mpsc_queue as mpsc; use sync::mpsc::select::StartResult::*; use sync::mpsc::select::StartResult; use sync::{Mutex, MutexGuard}; -use thread::Thread; +use thread; const DISCONNECTED: isize = isize::MIN; const FUDGE: isize = 1024; @@ -64,7 +64,7 @@ pub enum Failure { Disconnected, } -impl<T: Send> Packet<T> { +impl<T: Send + 'static> Packet<T> { // Creation of a packet *must* be followed by a call to postinit_lock // and later by inherit_blocker pub fn new() -> Packet<T> { @@ -194,7 +194,7 @@ impl<T: Send> Packet<T> { match self.queue.pop() { mpsc::Data(..) => {} mpsc::Empty => break, - mpsc::Inconsistent => Thread::yield_now(), + mpsc::Inconsistent => thread::yield_now(), } } // maybe we're done, if we're not the last ones @@ -283,7 +283,7 @@ impl<T: Send> Packet<T> { mpsc::Inconsistent => { let data; loop { - Thread::yield_now(); + thread::yield_now(); match self.queue.pop() { mpsc::Data(t) => { data = t; break } mpsc::Empty => panic!("inconsistent => empty"), @@ -460,7 +460,7 @@ impl<T: Send> Packet<T> { drop(self.take_to_wake()); } else { while self.to_wake.load(Ordering::SeqCst) != 0 { - Thread::yield_now(); + thread::yield_now(); } } // if the number of steals is -1, it was the pre-emptive -1 steal @@ -474,7 +474,7 @@ impl<T: Send> Packet<T> { } #[unsafe_destructor] -impl<T: Send> Drop for Packet<T> { +impl<T: Send + 'static> Drop for Packet<T> { fn drop(&mut self) { // Note that this load is not only an assert for correctness about // disconnection, but also a proper fence before the read of diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs index f0558c33d1e..b8f835bde51 100644 --- a/src/libstd/sync/mpsc/spsc_queue.rs +++ b/src/libstd/sync/mpsc/spsc_queue.rs @@ -74,11 +74,11 @@ pub struct Queue<T> { cache_subtractions: AtomicUsize, } -unsafe impl<T: Send> Send for Queue<T> { } +unsafe impl<T: Send + 'static> Send for Queue<T> { } -unsafe impl<T: Send> Sync for Queue<T> { } +unsafe impl<T: Send + 'static> Sync for Queue<T> { } -impl<T: Send> Node<T> { +impl<T: Send + 'static> Node<T> { fn new() -> *mut Node<T> { unsafe { mem::transmute(box Node { @@ -89,7 +89,7 @@ impl<T: Send> Node<T> { } } -impl<T: Send> Queue<T> { +impl<T: Send + 'static> Queue<T> { /// Creates a new queue. /// /// This is unsafe as the type system doesn't enforce a single @@ -227,7 +227,7 @@ impl<T: Send> Queue<T> { } #[unsafe_destructor] -impl<T: Send> Drop for Queue<T> { +impl<T: Send + 'static> Drop for Queue<T> { fn drop(&mut self) { unsafe { let mut cur = *self.first.get(); @@ -246,7 +246,7 @@ mod test { use sync::Arc; use super::Queue; - use thread::Thread; + use thread; use sync::mpsc::channel; #[test] @@ -324,7 +324,7 @@ mod test { let (tx, rx) = channel(); let q2 = q.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { for _ in 0u..100000 { loop { match q2.pop() { diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index ab9bd6b2ed7..a194c996692 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -26,7 +26,7 @@ use core::prelude::*; use core::cmp; use core::isize; -use thread::Thread; +use thread; use sync::atomic::{AtomicIsize, AtomicUsize, Ordering, AtomicBool}; use sync::mpsc::Receiver; @@ -74,7 +74,7 @@ enum Message<T> { GoUp(Receiver<T>), } -impl<T: Send> Packet<T> { +impl<T: Send + 'static> Packet<T> { pub fn new() -> Packet<T> { Packet { queue: unsafe { spsc::Queue::new(128) }, @@ -440,7 +440,7 @@ impl<T: Send> Packet<T> { drop(self.take_to_wake()); } else { while self.to_wake.load(Ordering::SeqCst) != 0 { - Thread::yield_now(); + thread::yield_now(); } } assert_eq!(self.steals, 0); @@ -472,7 +472,7 @@ impl<T: Send> Packet<T> { } #[unsafe_destructor] -impl<T: Send> Drop for Packet<T> { +impl<T: Send + 'static> Drop for Packet<T> { fn drop(&mut self) { // Note that this load is not only an assert for correctness about // disconnection, but also a proper fence before the read of diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index da3ce51a652..ae96a2491dc 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -55,9 +55,9 @@ pub struct Packet<T> { lock: Mutex<State<T>>, } -unsafe impl<T:Send> Send for Packet<T> { } +unsafe impl<T: Send + 'static> Send for Packet<T> { } -unsafe impl<T:Send> Sync for Packet<T> { } +unsafe impl<T: Send + 'static> Sync for Packet<T> { } struct State<T> { disconnected: bool, // Is the channel disconnected yet? @@ -75,7 +75,7 @@ struct State<T> { canceled: Option<&'static mut bool>, } -unsafe impl<T: Send> Send for State<T> {} +unsafe impl<T: Send + 'static> Send for State<T> {} /// Possible flavors of threads who can be blocked on this channel. enum Blocker { @@ -113,7 +113,7 @@ pub enum Failure { /// Atomically blocks the current thread, placing it into `slot`, unlocking `lock` /// in the meantime. This re-locks the mutex upon returning. -fn wait<'a, 'b, T: Send>(lock: &'a Mutex<State<T>>, +fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex<State<T>>, mut guard: MutexGuard<'b, State<T>>, f: fn(SignalToken) -> Blocker) -> MutexGuard<'a, State<T>> @@ -136,7 +136,7 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) { token.signal(); } -impl<T: Send> Packet<T> { +impl<T: Send + 'static> Packet<T> { pub fn new(cap: uint) -> Packet<T> { Packet { channels: AtomicUsize::new(1), @@ -412,7 +412,7 @@ impl<T: Send> Packet<T> { } #[unsafe_destructor] -impl<T: Send> Drop for Packet<T> { +impl<T: Send + 'static> Drop for Packet<T> { fn drop(&mut self) { assert_eq!(self.channels.load(Ordering::SeqCst), 0); let mut guard = self.lock.lock().unwrap(); diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 74692c1273c..65cae90857e 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -47,7 +47,7 @@ use sys_common::mutex as sys; /// /// ```rust /// use std::sync::{Arc, Mutex}; -/// use std::thread::Thread; +/// use std::thread; /// use std::sync::mpsc::channel; /// /// const N: uint = 10; @@ -62,7 +62,7 @@ use sys_common::mutex as sys; /// let (tx, rx) = channel(); /// for _ in 0u..10 { /// let (data, tx) = (data.clone(), tx.clone()); -/// Thread::spawn(move || { +/// thread::spawn(move || { /// // The shared static can only be accessed once the lock is held. /// // Our non-atomic increment is safe because we're the only thread /// // which can access the shared state when the lock is held. @@ -85,12 +85,12 @@ use sys_common::mutex as sys; /// /// ```rust /// use std::sync::{Arc, Mutex}; -/// use std::thread::Thread; +/// use std::thread; /// /// let lock = Arc::new(Mutex::new(0u)); /// let lock2 = lock.clone(); /// -/// let _ = Thread::scoped(move || -> () { +/// let _ = thread::spawn(move || -> () { /// // This thread will acquire the mutex first, unwrapping the result of /// // `lock` because the lock has not been poisoned. /// let _lock = lock2.lock().unwrap(); @@ -120,9 +120,9 @@ pub struct Mutex<T> { data: UnsafeCell<T>, } -unsafe impl<T:Send> Send for Mutex<T> { } +unsafe impl<T: Send + 'static> Send for Mutex<T> { } -unsafe impl<T:Send> Sync for Mutex<T> { } +unsafe impl<T: Send + 'static> Sync for Mutex<T> { } /// The static mutex type is provided to allow for static allocation of mutexes. /// @@ -180,7 +180,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex { poison: poison::FLAG_INIT, }; -impl<T: Send> Mutex<T> { +impl<T: Send + 'static> Mutex<T> { /// Creates a new mutex in an unlocked state ready for use. #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> Mutex<T> { @@ -243,7 +243,7 @@ impl<T: Send> Mutex<T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> Drop for Mutex<T> { +impl<T: Send + 'static> 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 @@ -350,7 +350,7 @@ mod test { use sync::mpsc::channel; use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar}; - use thread::Thread; + use thread; struct Packet<T>(Arc<(Mutex<T>, Condvar)>); @@ -393,9 +393,9 @@ mod test { let (tx, rx) = channel(); for _ in 0..K { let tx2 = tx.clone(); - Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); + thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); let tx2 = tx.clone(); - Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); + thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); } drop(tx); @@ -419,7 +419,7 @@ mod test { let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); let packet2 = Packet(packet.0.clone()); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { // wait until parent gets in rx.recv().unwrap(); let &(ref lock, ref cvar) = &*packet2.0; @@ -443,7 +443,7 @@ mod test { let packet2 = Packet(packet.0.clone()); let (tx, rx) = channel(); - let _t = Thread::spawn(move || -> () { + let _t = thread::spawn(move || -> () { rx.recv().unwrap(); let &(ref lock, ref cvar) = &*packet2.0; let _g = lock.lock().unwrap(); @@ -471,7 +471,7 @@ mod test { let arc = Arc::new(Mutex::new(1)); assert!(!arc.is_poisoned()); let arc2 = arc.clone(); - let _ = Thread::scoped(move|| { + let _ = thread::spawn(move|| { let lock = arc2.lock().unwrap(); assert_eq!(*lock, 2); }).join(); @@ -486,7 +486,7 @@ mod test { let arc = Arc::new(Mutex::new(1)); let arc2 = Arc::new(Mutex::new(arc)); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let lock = arc2.lock().unwrap(); let lock2 = lock.lock().unwrap(); assert_eq!(*lock2, 1); @@ -499,7 +499,7 @@ mod test { fn test_mutex_arc_access_in_unwind() { let arc = Arc::new(Mutex::new(1)); let arc2 = arc.clone(); - let _ = Thread::scoped(move|| -> () { + let _ = thread::spawn(move|| -> () { struct Unwinder { i: Arc<Mutex<int>>, } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 29c2051e5ad..1e87c0d612b 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -127,7 +127,7 @@ impl Once { mod test { use prelude::v1::*; - use thread::Thread; + use thread; use super::{ONCE_INIT, Once}; use sync::mpsc::channel; @@ -149,8 +149,8 @@ mod test { let (tx, rx) = channel(); for _ in 0u..10 { let tx = tx.clone(); - Thread::spawn(move|| { - for _ in 0u..4 { Thread::yield_now() } + thread::spawn(move|| { + for _ in 0u..4 { thread::yield_now() } unsafe { O.call_once(|| { assert!(!run); diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index a93bd31f5ae..32c8150ba40 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -13,7 +13,7 @@ use prelude::v1::*; use cell::UnsafeCell; use error::{Error, FromError}; use fmt; -use thread::Thread; +use thread; pub struct Flag { failed: UnsafeCell<bool> } pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } }; @@ -21,7 +21,7 @@ pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } }; impl Flag { #[inline] pub fn borrow(&self) -> LockResult<Guard> { - let ret = Guard { panicking: Thread::panicking() }; + let ret = Guard { panicking: thread::panicking() }; if unsafe { *self.failed.get() } { Err(PoisonError::new(ret)) } else { @@ -31,7 +31,7 @@ impl Flag { #[inline] pub fn done(&self, guard: &Guard) { - if !guard.panicking && Thread::panicking() { + if !guard.panicking && thread::panicking() { unsafe { *self.failed.get() = true; } } } diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index c4f1f2ccadd..b8d157d341e 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -400,7 +400,7 @@ mod tests { use rand::{self, Rng}; use sync::mpsc::channel; - use thread::Thread; + use thread; use sync::{Arc, RwLock, StaticRwLock, RW_LOCK_INIT}; #[test] @@ -425,13 +425,13 @@ mod tests { #[test] fn frob() { static R: StaticRwLock = RW_LOCK_INIT; - static N: uint = 10; - static M: uint = 1000; + static N: usize = 10; + static M: usize = 1000; let (tx, rx) = channel::<()>(); for _ in 0..N { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut rng = rand::thread_rng(); for _ in 0..M { if rng.gen_weighted_bool(N) { @@ -452,7 +452,7 @@ mod tests { fn test_rw_arc_poison_wr() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); - let _: Result<uint, _> = Thread::scoped(move|| { + let _: Result<(), _> = thread::spawn(move|| { let _lock = arc2.write().unwrap(); panic!(); }).join(); @@ -464,7 +464,7 @@ mod tests { let arc = Arc::new(RwLock::new(1)); assert!(!arc.is_poisoned()); let arc2 = arc.clone(); - let _: Result<uint, _> = Thread::scoped(move|| { + let _: Result<(), _> = thread::spawn(move|| { let _lock = arc2.write().unwrap(); panic!(); }).join(); @@ -476,7 +476,7 @@ mod tests { fn test_rw_arc_no_poison_rr() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); - let _: Result<uint, _> = Thread::scoped(move|| { + let _: Result<(), _> = thread::spawn(move|| { let _lock = arc2.read().unwrap(); panic!(); }).join(); @@ -487,7 +487,7 @@ mod tests { fn test_rw_arc_no_poison_rw() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); - let _: Result<uint, _> = Thread::scoped(move|| { + let _: Result<(), _> = thread::spawn(move|| { let _lock = arc2.read().unwrap(); panic!() }).join(); @@ -501,12 +501,12 @@ mod tests { let arc2 = arc.clone(); let (tx, rx) = channel(); - Thread::spawn(move|| { + thread::spawn(move|| { let mut lock = arc2.write().unwrap(); for _ in 0u..10 { let tmp = *lock; *lock = -1; - Thread::yield_now(); + thread::yield_now(); *lock = tmp + 1; } tx.send(()).unwrap(); @@ -516,7 +516,7 @@ mod tests { let mut children = Vec::new(); for _ in 0u..5 { let arc3 = arc.clone(); - children.push(Thread::scoped(move|| { + children.push(thread::spawn(move|| { let lock = arc3.read().unwrap(); assert!(*lock >= 0); })); @@ -537,7 +537,7 @@ mod tests { fn test_rw_arc_access_in_unwind() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); - let _ = Thread::scoped(move|| -> () { + let _ = thread::spawn(move|| -> () { struct Unwinder { i: Arc<RwLock<int>>, } diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs index 0304b898884..410e1c11bb9 100644 --- a/src/libstd/sync/semaphore.rs +++ b/src/libstd/sync/semaphore.rs @@ -114,7 +114,7 @@ mod tests { use sync::Arc; use super::Semaphore; use sync::mpsc::channel; - use thread::Thread; + use thread; #[test] fn test_sem_acquire_release() { @@ -134,7 +134,7 @@ mod tests { fn test_sem_as_mutex() { let s = Arc::new(Semaphore::new(1)); let s2 = s.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _g = s2.access(); }); let _g = s.access(); @@ -146,7 +146,7 @@ mod tests { let (tx, rx) = channel(); let s = Arc::new(Semaphore::new(0)); let s2 = s.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { s2.acquire(); tx.send(()).unwrap(); }); @@ -157,7 +157,7 @@ mod tests { let (tx, rx) = channel(); let s = Arc::new(Semaphore::new(0)); let s2 = s.clone(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { s2.release(); let _ = rx.recv(); }); @@ -173,7 +173,7 @@ mod tests { let s2 = s.clone(); let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { let _g = s2.access(); let _ = rx2.recv(); tx1.send(()).unwrap(); @@ -190,7 +190,7 @@ mod tests { let (tx, rx) = channel(); { let _g = s.access(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(()).unwrap(); drop(s2.access()); tx.send(()).unwrap(); diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 684a46fd6ff..f4274dd91cc 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -20,16 +20,16 @@ use core::prelude::*; use sync::{Arc, Mutex}; use sync::mpsc::{channel, Sender, Receiver}; -use thread::Thread; +use thread; use thunk::Thunk; struct Sentinel<'a> { - jobs: &'a Arc<Mutex<Receiver<Thunk>>>, + jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>, active: bool } impl<'a> Sentinel<'a> { - fn new(jobs: &Arc<Mutex<Receiver<Thunk>>>) -> Sentinel { + fn new(jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>) -> Sentinel<'a> { Sentinel { jobs: jobs, active: true @@ -80,7 +80,7 @@ pub struct TaskPool { // // This is the only such Sender, so when it is dropped all subthreads will // quit. - jobs: Sender<Thunk> + jobs: Sender<Thunk<'static>> } impl TaskPool { @@ -105,14 +105,14 @@ impl TaskPool { /// Executes the function `job` on a thread in the pool. pub fn execute<F>(&self, job: F) - where F : FnOnce(), F : Send + where F : FnOnce(), F : Send + 'static { self.jobs.send(Thunk::new(job)).unwrap(); } } -fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) { - Thread::spawn(move || { +fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk<'static>>>>) { + thread::spawn(move || { // Will spawn a new thread on panic unless it is cancelled. let sentinel = Sentinel::new(&jobs); diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 255f474d4f4..dc1ae85efe0 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -30,7 +30,7 @@ use sync::{StaticMutex, StaticCondvar}; use sync::mpsc::{channel, Sender, Receiver}; use sys::helper_signal; -use thread::Thread; +use thread; /// A structure for management of a helper thread. /// @@ -81,7 +81,7 @@ impl<M: Send> Helper<M> { /// /// 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, + T: Send + 'static, F: FnOnce() -> T, { unsafe { @@ -95,7 +95,7 @@ impl<M: Send> Helper<M> { let receive = RaceBox(receive); let t = f(); - Thread::spawn(move || { + thread::spawn(move || { helper(receive.0, rx, t); let _g = self.lock.lock().unwrap(); *self.shutdown.get() = true; diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs index 92b936e74f6..65c706033f2 100644 --- a/src/libstd/sys/common/thread_info.rs +++ b/src/libstd/sys/common/thread_info.rs @@ -29,7 +29,7 @@ thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(N impl ThreadInfo { fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R { if THREAD_INFO.state() == State::Destroyed { - panic!("Use of std::thread::Thread::current() is not possible after \ + panic!("Use of std::thread::current() is not possible after \ the thread's local data has been destroyed"); } @@ -63,7 +63,7 @@ pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) { })); } -// a hack to get around privacy restrictions; implemented by `std::thread::Thread` +// a hack to get around privacy restrictions; implemented by `std::thread` pub trait NewThread { fn new(name: Option<String>) -> Self; } diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs index 905fac07c5d..27b8784e394 100644 --- a/src/libstd/sys/common/thread_local.rs +++ b/src/libstd/sys/common/thread_local.rs @@ -24,7 +24,7 @@ //! # Usage //! //! This module should likely not be used directly unless other primitives are -//! being built on. types such as `thread_local::scoped::Key` are likely much +//! being built on. types such as `thread_local::spawn::Key` are likely much //! more useful in practice than this OS-based version which likely requires //! unsafe code to interoperate with. //! diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 6047f94b3b4..b610f6c370b 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -817,7 +817,9 @@ impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 { } } -impl AsciiExt<Wtf8Buf> for Wtf8 { +impl AsciiExt for Wtf8 { + type Owned = Wtf8Buf; + fn is_ascii(&self) -> bool { self.bytes.is_ascii() } @@ -830,6 +832,9 @@ impl AsciiExt<Wtf8Buf> for Wtf8 { fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool { self.bytes.eq_ignore_ascii_case(&other.bytes) } + + fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() } + fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() } } #[cfg(test)] diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 8a6ef17818a..df03841276e 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -247,6 +247,10 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } } +impl ExactSizeIterator for Args { + fn len(&self) -> usize { self.iter.len() } +} + /// Returns the command line arguments /// /// Returns a list of the command line arguments. diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 6f030ee91fe..82c52471d10 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -10,6 +10,7 @@ use core::prelude::*; +use io; use boxed::Box; use cmp; use mem; @@ -191,7 +192,7 @@ pub mod guard { } } -pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { +pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> { let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); assert_eq!(pthread_attr_init(&mut attr), 0); @@ -226,9 +227,10 @@ pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { if ret != 0 { // be sure to not leak the closure let _p: Box<Box<FnOnce()+Send>> = mem::transmute(arg); - panic!("failed to spawn native thread: {}", ret); + Err(io::Error::from_os_error(ret)) + } else { + Ok(native) } - native } #[cfg(any(target_os = "linux", target_os = "android"))] diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 7e684c52341..502d70d4e1a 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -18,7 +18,7 @@ use os::windows::*; use error::Error as StdError; use ffi::{OsString, OsStr, AsOsStr}; use fmt; -use iter::Range; +use ops::Range; use libc::types::os::arch::extra::LPWCH; use libc::{self, c_int, c_void}; use mem; @@ -303,6 +303,10 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() } } +impl ExactSizeIterator for Args { + fn len(&self) -> usize { self.range.len() } +} + impl Drop for Args { fn drop(&mut self) { unsafe { c::LocalFree(self.cur as *mut c_void); } @@ -315,7 +319,7 @@ pub fn args() -> Args { let lpCmdLine = c::GetCommandLineW(); let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs); - Args { cur: szArgList, range: range(0, nArgs as isize) } + Args { cur: szArgList, range: 0..(nArgs as isize) } } } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index a38dc9b2d34..f3a27877e5c 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use boxed::Box; +use prelude::v1::*; + use cmp; +use io; use mem; use ptr; use libc; @@ -42,7 +44,7 @@ pub mod guard { } } -pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { +pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> { let arg: *mut libc::c_void = mem::transmute(box p); // FIXME On UNIX, we guard against stack sizes that are too small but // that's because pthreads enforces that stacks are at least @@ -60,9 +62,10 @@ pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { if ret as uint == 0 { // be sure to not leak the closure let _p: Box<Thunk> = mem::transmute(arg); - panic!("failed to spawn native thread: {:?}", ret); + Err(io::Error::last_os_error()) + } else { + Ok(ret) } - return ret; } pub unsafe fn set_name(_name: &str) { diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index cc9d7492441..3137d779c40 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -42,32 +42,32 @@ //! Already-running threads are represented via the `Thread` type, which you can //! get in one of two ways: //! -//! * By spawning a new thread, e.g. using the `Thread::spawn` constructor; -//! * By requesting the current thread, using the `Thread::current` function. +//! * By spawning a new thread, e.g. using the `thread::spawn` constructor; +//! * By requesting the current thread, using the `thread::current` function. //! //! Threads can be named, and provide some built-in support for low-level //! synchronization described below. //! -//! The `Thread::current()` function is available even for threads not spawned +//! The `thread::current()` function is available even for threads not spawned //! by the APIs of this module. //! //! ## Spawning a thread //! -//! A new thread can be spawned using the `Thread::spawn` function: +//! A new thread can be spawned using the `thread::spawn` function: //! //! ```rust -//! use std::thread::Thread; +//! use std::thread; //! -//! let thread = Thread::spawn(move || { +//! thread::spawn(move || { //! println!("Hello, World!"); //! // some computation here //! }); //! ``` //! -//! The spawned thread is "detached" from the current thread, meaning that it -//! can outlive the thread that spawned it. (Note, however, that when the main -//! thread terminates all detached threads are terminated as well.) The returned -//! `Thread` handle can be used for low-level synchronization as described below. +//! In this example, the spawned thread is "detached" from the current +//! thread, meaning that it can outlive the thread that spawned +//! it. (Note, however, that when the main thread terminates all +//! detached threads are terminated as well.) //! //! ## Scoped threads //! @@ -76,23 +76,23 @@ //! For this scenario, use the `scoped` constructor: //! //! ```rust -//! use std::thread::Thread; +//! use std::thread; //! -//! let guard = Thread::scoped(move || { +//! let guard = thread::scoped(move || { //! println!("Hello, World!"); //! // some computation here //! }); //! // do some other work in the meantime -//! let result = guard.join(); +//! let output = guard.join(); //! ``` //! -//! The `scoped` function doesn't return a `Thread` directly; instead, it -//! returns a *join guard* from which a `Thread` can be extracted. The join -//! guard is an RAII-style guard that will automatically join the child thread -//! (block until it terminates) when it is dropped. You can join the child -//! thread in advance by calling the `join` method on the guard, which will also -//! return the result produced by the thread. A handle to the thread itself is -//! available via the `thread` method on the join guard. +//! The `scoped` function doesn't return a `Thread` directly; instead, +//! it returns a *join guard*. The join guard is an RAII-style guard +//! that will automatically join the child thread (block until it +//! terminates) when it is dropped. You can join the child thread in +//! advance by calling the `join` method on the guard, which will also +//! return the result produced by the thread. A handle to the thread +//! itself is available via the `thread` method on the join guard. //! //! (Note: eventually, the `scoped` constructor will allow the parent and child //! threads to data that lives on the parent thread's stack, but some language @@ -120,10 +120,10 @@ //! Conceptually, each `Thread` handle has an associated token, which is //! initially not present: //! -//! * The `Thread::park()` function blocks the current thread unless or until +//! * The `thread::park()` function blocks the current thread unless or until //! the token is available for its thread handle, at which point It atomically //! consumes the token. It may also return *spuriously*, without consuming the -//! token. `Thread::park_timeout()` does the same, but allows specifying a +//! token. `thread::park_timeout()` does the same, but allows specifying a //! maximum time to block the thread for. //! //! * The `unpark()` method on a `Thread` atomically makes the token available @@ -147,19 +147,16 @@ #![stable(feature = "rust1", since = "1.0.0")] +use prelude::v1::*; + use any::Any; -use boxed::Box; use cell::UnsafeCell; -use clone::Clone; -use marker::{Send, Sync}; -use ops::{Drop, FnOnce}; -use option::Option::{self, Some, None}; -use result::Result::{Err, Ok}; -use sync::{Mutex, Condvar, Arc}; -use str::Str; -use string::String; +use fmt; +use io; +use marker; +use old_io::stdio; use rt::{self, unwind}; -use old_io::{Writer, stdio}; +use sync::{Mutex, Condvar, Arc}; use thunk::Thunk; use time::Duration; @@ -175,9 +172,9 @@ pub struct Builder { // The size of the stack for the spawned thread stack_size: Option<uint>, // Thread-local stdout - stdout: Option<Box<Writer + Send>>, + stdout: Option<Box<Writer + Send + 'static>>, // Thread-local stderr - stderr: Option<Box<Writer + Send>>, + stderr: Option<Box<Writer + Send + 'static>>, } impl Builder { @@ -211,7 +208,7 @@ impl Builder { /// Redirect thread-local stdout. #[unstable(feature = "std_misc", reason = "Will likely go away after proc removal")] - pub fn stdout(mut self, stdout: Box<Writer + Send>) -> Builder { + pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder { self.stdout = Some(stdout); self } @@ -219,54 +216,65 @@ impl Builder { /// Redirect thread-local stderr. #[unstable(feature = "std_misc", reason = "Will likely go away after proc removal")] - pub fn stderr(mut self, stderr: Box<Writer + Send>) -> Builder { + pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder { self.stderr = Some(stderr); self } - /// Spawn a new detached thread, and return a handle to it. + /// Spawn a new thread, and return a join handle for it. /// - /// See `Thead::spawn` and the module doc for more details. - #[unstable(feature = "std_misc", - reason = "may change with specifics of new Send semantics")] - pub fn spawn<F>(self, f: F) -> Thread where F: FnOnce(), F: Send + 'static { - let (native, thread) = self.spawn_inner(Thunk::new(f), Thunk::with_arg(|_| {})); - unsafe { imp::detach(native) }; - thread + /// The child thread may outlive the parent (unless the parent thread + /// is the main thread; the whole process is terminated when the main + /// thread finishes.) The join handle can be used to block on + /// termination of the child thread, including recovering its panics. + /// + /// # Errors + /// + /// Unlike the `spawn` free function, this method yields an + /// `io::Result` to capture any failure to create the thread at + /// the OS level. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn spawn<F>(self, f: F) -> io::Result<JoinHandle> where + F: FnOnce(), F: Send + 'static + { + self.spawn_inner(Thunk::new(f)).map(|i| JoinHandle(i)) } /// Spawn a new child thread that must be joined within a given /// scope, and return a `JoinGuard`. /// - /// See `Thead::scoped` and the module doc for more details. - #[unstable(feature = "std_misc", - reason = "may change with specifics of new Send semantics")] - pub fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T> where + /// The join guard can be used to explicitly join the child thread (via + /// `join`), returning `Result<T>`, or it will implicitly join the child + /// upon being dropped. Because the child thread may refer to data on the + /// current thread's stack (hence the "scoped" name), it cannot be detached; + /// it *must* be joined before the relevant stack frame is popped. See the + /// module documentation for additional details. + /// + /// # Errors + /// + /// Unlike the `scoped` free function, this method yields an + /// `io::Result` to capture any failure to create the thread at + /// the OS level. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { - let my_packet = Packet(Arc::new(UnsafeCell::new(None))); - let their_packet = Packet(my_packet.0.clone()); - let (native, thread) = self.spawn_inner(Thunk::new(f), Thunk::with_arg(move |ret| unsafe { - *their_packet.0.get() = Some(ret); - })); - - JoinGuard { - native: native, - joined: false, - packet: my_packet, - thread: thread, - } + self.spawn_inner(Thunk::new(f)).map(|inner| { + JoinGuard { inner: inner, _marker: marker::CovariantType } + }) } - fn spawn_inner<T: Send>(self, f: Thunk<(), T>, finish: Thunk<Result<T>, ()>) - -> (imp::rust_thread, Thread) - { + fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> { let Builder { name, stack_size, stdout, stderr } = self; let stack_size = stack_size.unwrap_or(rt::min_stack()); + let my_thread = Thread::new(name); let their_thread = my_thread.clone(); + let my_packet = Packet(Arc::new(UnsafeCell::new(None))); + let their_packet = Packet(my_packet.0.clone()); + // Spawning a new OS thread guarantees that __morestack will never get // triggered, but we must manually set up the actual stack bounds once // this function starts executing. This raises the lower limit by a bit @@ -316,17 +324,120 @@ impl Builder { unwind::try(move || *ptr = Some(f.invoke(()))) } }; - finish.invoke(match (output, try_result) { - (Some(data), Ok(_)) => Ok(data), - (None, Err(cause)) => Err(cause), - _ => unreachable!() - }); + unsafe { + *their_packet.0.get() = Some(match (output, try_result) { + (Some(data), Ok(_)) => Ok(data), + (None, Err(cause)) => Err(cause), + _ => unreachable!() + }); + } }; - (unsafe { imp::create(stack_size, Thunk::new(main)) }, my_thread) + Ok(JoinInner { + native: try!(unsafe { imp::create(stack_size, Thunk::new(main)) }), + thread: my_thread, + packet: my_packet, + joined: false, + }) + } +} + +/// Spawn a new, returning a join handle for it. +/// +/// The child thread may outlive the parent (unless the parent thread +/// is the main thread; the whole process is terminated when the main +/// thread finishes.) The join handle can be used to block on +/// termination of the child thread, including recovering its panics. +/// +/// # Panics +/// +/// Panicks if the OS fails to create a thread; use `Builder::spawn` +/// to recover from such errors. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static { + Builder::new().spawn(f).unwrap() +} + +/// Spawn a new *scoped* thread, returning a `JoinGuard` for it. +/// +/// The join guard can be used to explicitly join the child thread (via +/// `join`), returning `Result<T>`, or it will implicitly join the child +/// upon being dropped. Because the child thread may refer to data on the +/// current thread's stack (hence the "scoped" name), it cannot be detached; +/// it *must* be joined before the relevant stack frame is popped. See the +/// module documentation for additional details. +/// +/// # Panics +/// +/// Panicks if the OS fails to create a thread; use `Builder::scoped` +/// to recover from such errors. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where + T: Send + 'a, F: FnOnce() -> T, F: Send + 'a +{ + Builder::new().scoped(f).unwrap() +} + +/// Gets a handle to the thread that invokes it. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn current() -> Thread { + thread_info::current_thread() +} + +/// Cooperatively give up a timeslice to the OS scheduler. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn yield_now() { + unsafe { imp::yield_now() } +} + +/// Determines whether the current thread is unwinding because of panic. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn panicking() -> bool { + unwind::panicking() +} + +/// Block unless or until the current thread's token is made available (may wake spuriously). +/// +/// See the module doc for more detail. +// +// The implementation currently uses the trivial strategy of a Mutex+Condvar +// with wakeup flag, which does not actually allow spurious wakeups. In the +// future, this will be implemented in a more efficient way, perhaps along the lines of +// http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp +// or futuxes, and in either case may allow spurious wakeups. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn park() { + let thread = current(); + let mut guard = thread.inner.lock.lock().unwrap(); + while !*guard { + guard = thread.inner.cvar.wait(guard).unwrap(); } + *guard = false; +} + +/// Block unless or until the current thread's token is made available or +/// the specified duration has been reached (may wake spuriously). +/// +/// The semantics of this function are equivalent to `park()` except that the +/// thread will be blocked for roughly no longer than dur. This method +/// should not be used for precise timing due to anomalies such as +/// preemption or platform differences that may not cause the maximum +/// amount of time waited to be precisely dur +/// +/// See the module doc for more detail. +#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")] +pub fn park_timeout(dur: Duration) { + let thread = current(); + let mut guard = thread.inner.lock.lock().unwrap(); + if !*guard { + let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap(); + guard = g; + } + *guard = false; } +/// The internal representation of a `Thread` handle struct Inner { name: Option<String>, lock: Mutex<bool>, // true when there is a buffered unpark @@ -354,65 +465,51 @@ impl Thread { } } - /// Spawn a new detached thread, returning a handle to it. - /// - /// The child thread may outlive the parent (unless the parent thread is the - /// main thread; the whole process is terminated when the main thread - /// finishes.) The thread handle can be used for low-level - /// synchronization. See the module documentation for additional details. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[unstable(feature = "std_misc", reason = "may change with specifics of new Send semantics")] pub fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static { - Builder::new().spawn(f) + Builder::new().spawn(f).unwrap().thread().clone() } - /// Spawn a new *scoped* thread, returning a `JoinGuard` for it. - /// - /// The join guard can be used to explicitly join the child thread (via - /// `join`), returning `Result<T>`, or it will implicitly join the child - /// upon being dropped. Because the child thread may refer to data on the - /// current thread's stack (hence the "scoped" name), it cannot be detached; - /// it *must* be joined before the relevant stack frame is popped. See the - /// module documentation for additional details. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[unstable(feature = "std_misc", reason = "may change with specifics of new Send semantics")] pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { - Builder::new().scoped(f) + Builder::new().scoped(f).unwrap() } - /// Gets a handle to the thread that invokes it. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[stable(feature = "rust1", since = "1.0.0")] pub fn current() -> Thread { thread_info::current_thread() } - /// Cooperatively give up a timeslice to the OS scheduler. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[unstable(feature = "std_misc", reason = "name may change")] pub fn yield_now() { unsafe { imp::yield_now() } } - /// Determines whether the current thread is unwinding because of panic. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn panicking() -> bool { unwind::panicking() } - /// Block unless or until the current thread's token is made available (may wake spuriously). - /// - /// See the module doc for more detail. - // - // The implementation currently uses the trivial strategy of a Mutex+Condvar - // with wakeup flag, which does not actually allow spurious wakeups. In the - // future, this will be implemented in a more efficient way, perhaps along the lines of - // http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp - // or futuxes, and in either case may allow spurious wakeups. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[unstable(feature = "std_misc", reason = "recently introduced")] pub fn park() { - let thread = Thread::current(); + let thread = current(); let mut guard = thread.inner.lock.lock().unwrap(); while !*guard { guard = thread.inner.cvar.wait(guard).unwrap(); @@ -420,19 +517,11 @@ impl Thread { *guard = false; } - /// Block unless or until the current thread's token is made available or - /// the specified duration has been reached (may wake spuriously). - /// - /// The semantics of this function are equivalent to `park()` except that the - /// thread will be blocked for roughly no longer than dur. This method - /// should not be used for precise timing due to anomalies such as - /// preemption or platform differences that may not cause the maximum - /// amount of time waited to be precisely dur - /// - /// See the module doc for more detail. + /// Deprecated: use module-level free fucntion. + #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")] #[unstable(feature = "std_misc", reason = "recently introduced")] pub fn park_timeout(dur: Duration) { - let thread = Thread::current(); + let thread = current(); let mut guard = thread.inner.lock.lock().unwrap(); if !*guard { let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap(); @@ -444,7 +533,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// See the module doc for more detail. - #[unstable(feature = "std_misc", reason = "recently introduced")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { let mut guard = self.inner.lock.lock().unwrap(); if !*guard { @@ -460,6 +549,13 @@ impl Thread { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Thread { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.name(), f) + } +} + // a hack to get around privacy restrictions impl thread_info::NewThread for Thread { fn new(name: Option<String>) -> Thread { Thread::new(name) } @@ -469,24 +565,84 @@ impl thread_info::NewThread for Thread { /// /// A thread that completes without panicking is considered to exit successfully. #[stable(feature = "rust1", since = "1.0.0")] -pub type Result<T> = ::result::Result<T, Box<Any + Send>>; +pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>; struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>); -unsafe impl<T:'static+Send> Send for Packet<T> {} +unsafe impl<T:Send> Send for Packet<T> {} unsafe impl<T> Sync for Packet<T> {} +/// Inner representation for JoinHandle and JoinGuard +struct JoinInner<T> { + native: imp::rust_thread, + thread: Thread, + packet: Packet<T>, + joined: bool, +} + +impl<T> JoinInner<T> { + fn join(&mut self) -> Result<T> { + assert!(!self.joined); + unsafe { imp::join(self.native) }; + self.joined = true; + unsafe { + (*self.packet.0.get()).take().unwrap() + } + } +} + +/// An owned permission to join on a thread (block on its termination). +/// +/// Unlike a `JoinGuard`, a `JoinHandle` *detaches* the child thread +/// when it is dropped, rather than automatically joining on drop. +/// +/// Due to platform restrictions, it is not possible to `Clone` this +/// handle: the ability to join a child thread is a uniquely-owned +/// permission. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct JoinHandle(JoinInner<()>); + +impl JoinHandle { + /// Extract a handle to the underlying thread + #[stable(feature = "rust1", since = "1.0.0")] + pub fn thread(&self) -> &Thread { + &self.0.thread + } + + /// Wait for the associated thread to finish. + /// + /// If the child thread panics, `Err` is returned with the parameter given + /// to `panic`. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn join(mut self) -> Result<()> { + self.0.join() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Drop for JoinHandle { + fn drop(&mut self) { + if !self.0.joined { + unsafe { imp::detach(self.0.native) } + } + } +} + /// An RAII-style guard that will block until thread termination when dropped. /// /// The type `T` is the return type for the thread's main function. +/// +/// Joining on drop is necessary to ensure memory safety when stack +/// data is shared between a parent and child thread. +/// +/// Due to platform restrictions, it is not possible to `Clone` this +/// handle: the ability to join a child thread is a uniquely-owned +/// permission. #[must_use] -#[unstable(feature = "std_misc", - reason = "may change with specifics of new Send semantics")] +#[stable(feature = "rust1", since = "1.0.0")] pub struct JoinGuard<'a, T: 'a> { - native: imp::rust_thread, - thread: Thread, - joined: bool, - packet: Packet<T>, + inner: JoinInner<T>, + _marker: marker::CovariantType<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] @@ -496,32 +652,32 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> { /// Extract a handle to the thread this guard will join on. #[stable(feature = "rust1", since = "1.0.0")] pub fn thread(&self) -> &Thread { - &self.thread + &self.inner.thread } /// Wait for the associated thread to finish, returning the result of the thread's /// calculation. /// - /// If the child thread panics, `Err` is returned with the parameter given - /// to `panic`. + /// # Panics + /// + /// Panics on the child thread are propagated by panicking the parent. #[stable(feature = "rust1", since = "1.0.0")] - pub fn join(mut self) -> Result<T> { - assert!(!self.joined); - unsafe { imp::join(self.native) }; - self.joined = true; - unsafe { - (*self.packet.0.get()).take().unwrap() + pub fn join(mut self) -> T { + match self.inner.join() { + Ok(res) => res, + Err(_) => panic!("child thread {:?} panicked", self.thread()), } } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> JoinGuard<'static, T> { /// Detaches the child thread, allowing it to outlive its parent. - #[unstable(feature = "std_misc", - reason = "unsure whether this API imposes limitations elsewhere")] + #[deprecated(since = "1.0.0", reason = "use spawn instead")] + #[unstable(feature = "std_misc")] pub fn detach(mut self) { - unsafe { imp::detach(self.native) }; - self.joined = true; // avoid joining in the destructor + unsafe { imp::detach(self.inner.native) }; + self.inner.joined = true; // avoid joining in the destructor } } @@ -529,8 +685,10 @@ impl<T: Send> JoinGuard<'static, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> { fn drop(&mut self) { - if !self.joined { - unsafe { imp::join(self.native) }; + if !self.inner.joined { + if self.inner.join().is_err() { + panic!("child thread {:?} panicked", self.thread()); + } } } } @@ -545,6 +703,7 @@ mod test { use result; use std::old_io::{ChanReader, ChanWriter}; use super::{Thread, Builder}; + use thread; use thunk::Thunk; use time::Duration; @@ -553,22 +712,22 @@ mod test { #[test] fn test_unnamed_thread() { - Thread::scoped(move|| { - assert!(Thread::current().name().is_none()); + thread::spawn(move|| { + assert!(thread::current().name().is_none()); }).join().ok().unwrap(); } #[test] fn test_named_thread() { Builder::new().name("ada lovelace".to_string()).scoped(move|| { - assert!(Thread::current().name().unwrap() == "ada lovelace".to_string()); - }).join().ok().unwrap(); + assert!(thread::current().name().unwrap() == "ada lovelace".to_string()); + }).unwrap().join(); } #[test] fn test_run_basic() { let (tx, rx) = channel(); - Thread::spawn(move|| { + thread::spawn(move|| { tx.send(()).unwrap(); }); rx.recv().unwrap(); @@ -576,17 +735,14 @@ mod test { #[test] fn test_join_success() { - match Thread::scoped(move|| -> String { + assert!(thread::scoped(move|| -> String { "Success!".to_string() - }).join().as_ref().map(|s| &**s) { - result::Result::Ok("Success!") => (), - _ => panic!() - } + }).join() == "Success!"); } #[test] fn test_join_panic() { - match Thread::scoped(move|| { + match thread::spawn(move|| { panic!() }).join() { result::Result::Err(_) => (), @@ -595,6 +751,26 @@ mod test { } #[test] + fn test_scoped_success() { + let res = thread::scoped(move|| -> String { + "Success!".to_string() + }).join(); + assert!(res == "Success!"); + } + + #[test] + #[should_fail] + fn test_scoped_panic() { + thread::scoped(|| panic!()).join(); + } + + #[test] + #[should_fail] + fn test_scoped_implicit_panic() { + thread::scoped(|| panic!()); + } + + #[test] fn test_spawn_sched() { use clone::Clone; @@ -602,7 +778,7 @@ mod test { fn f(i: int, tx: Sender<()>) { let tx = tx.clone(); - Thread::spawn(move|| { + thread::spawn(move|| { if i == 0 { tx.send(()).unwrap(); } else { @@ -619,8 +795,8 @@ mod test { fn test_spawn_sched_childs_on_default_sched() { let (tx, rx) = channel(); - Thread::spawn(move|| { - Thread::spawn(move|| { + thread::spawn(move|| { + thread::spawn(move|| { tx.send(()).unwrap(); }); }); @@ -628,7 +804,7 @@ mod test { rx.recv().unwrap(); } - fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) { + fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) { let (tx, rx) = channel::<uint>(); let x = box 1; @@ -646,14 +822,14 @@ mod test { #[test] fn test_avoid_copying_the_body_spawn() { avoid_copying_the_body(|v| { - Thread::spawn(move || v.invoke(())); + thread::spawn(move || v.invoke(())); }); } #[test] fn test_avoid_copying_the_body_thread_spawn() { avoid_copying_the_body(|f| { - Thread::spawn(move|| { + thread::spawn(move|| { f.invoke(()); }); }) @@ -662,7 +838,7 @@ mod test { #[test] fn test_avoid_copying_the_body_join() { avoid_copying_the_body(|f| { - let _ = Thread::scoped(move|| { + let _ = thread::spawn(move|| { f.invoke(()) }).join(); }) @@ -675,24 +851,24 @@ mod test { // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) static GENERATIONS: uint = 16; - fn child_no(x: uint) -> Thunk { + fn child_no(x: uint) -> Thunk<'static> { return Thunk::new(move|| { if x < GENERATIONS { - Thread::spawn(move|| child_no(x+1).invoke(())); + thread::spawn(move|| child_no(x+1).invoke(())); } }); } - Thread::spawn(|| child_no(0).invoke(())); + thread::spawn(|| child_no(0).invoke(())); } #[test] fn test_simple_newsched_spawn() { - Thread::spawn(move || {}); + thread::spawn(move || {}); } #[test] fn test_try_panic_message_static_str() { - match Thread::scoped(move|| { + match thread::spawn(move|| { panic!("static string"); }).join() { Err(e) => { @@ -706,7 +882,7 @@ mod test { #[test] fn test_try_panic_message_owned_str() { - match Thread::scoped(move|| { + match thread::spawn(move|| { panic!("owned string".to_string()); }).join() { Err(e) => { @@ -720,7 +896,7 @@ mod test { #[test] fn test_try_panic_message_any() { - match Thread::scoped(move|| { + match thread::spawn(move|| { panic!(box 413u16 as Box<Any + Send>); }).join() { Err(e) => { @@ -738,7 +914,7 @@ mod test { fn test_try_panic_message_unit_struct() { struct Juju; - match Thread::scoped(move|| { + match thread::spawn(move|| { panic!(Juju) }).join() { Err(ref e) if e.is::<Juju>() => {} @@ -752,10 +928,9 @@ mod test { let mut reader = ChanReader::new(rx); let stdout = ChanWriter::new(tx); - let r = Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| { + Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| { print!("Hello, world!"); - }).join(); - assert!(r.is_ok()); + }).unwrap().join(); let output = reader.read_to_string().unwrap(); assert_eq!(output, "Hello, world!".to_string()); @@ -764,15 +939,15 @@ mod test { #[test] fn test_park_timeout_unpark_before() { for _ in 0..10 { - Thread::current().unpark(); - Thread::park_timeout(Duration::seconds(10_000_000)); + thread::current().unpark(); + thread::park_timeout(Duration::seconds(10_000_000)); } } #[test] fn test_park_timeout_unpark_not_called() { for _ in 0..10 { - Thread::park_timeout(Duration::milliseconds(10)); + thread::park_timeout(Duration::milliseconds(10)); } } @@ -781,14 +956,14 @@ mod test { use std::old_io; for _ in 0..10 { - let th = Thread::current(); + let th = thread::current(); - let _guard = Thread::scoped(move || { + let _guard = thread::spawn(move || { old_io::timer::sleep(Duration::milliseconds(50)); th.unpark(); }); - Thread::park_timeout(Duration::seconds(10_000_000)); + thread::park_timeout(Duration::seconds(10_000_000)); } } diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index eab9cd84539..2ed296e081c 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -72,7 +72,7 @@ pub mod __impl { /// /// ``` /// use std::cell::RefCell; -/// use std::thread::Thread; +/// use std::thread; /// /// thread_local!(static FOO: RefCell<uint> = RefCell::new(1)); /// @@ -82,7 +82,7 @@ pub mod __impl { /// }); /// /// // each thread starts out with the initial value of 1 -/// Thread::spawn(move|| { +/// thread::spawn(move|| { /// FOO.with(|f| { /// assert_eq!(*f.borrow(), 1); /// *f.borrow_mut() = 3; @@ -548,7 +548,7 @@ mod tests { use sync::mpsc::{channel, Sender}; use cell::UnsafeCell; use super::State; - use thread::Thread; + use thread; struct Foo(Sender<()>); @@ -568,7 +568,7 @@ mod tests { *f.get() = 2; }); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { + let _t = thread::spawn(move|| { FOO.with(|f| unsafe { assert_eq!(*f.get(), 1); }); @@ -595,7 +595,7 @@ mod tests { } thread_local!(static FOO: Foo = foo()); - Thread::scoped(|| { + thread::spawn(|| { assert!(FOO.state() == State::Uninitialized); FOO.with(|_| { assert!(FOO.state() == State::Valid); @@ -611,7 +611,7 @@ mod tests { }); let (tx, rx) = channel(); - let _t = Thread::spawn(move|| unsafe { + let _t = thread::spawn(move|| unsafe { let mut tx = Some(tx); FOO.with(|f| { *f.get() = Some(Foo(tx.take().unwrap())); @@ -659,7 +659,7 @@ mod tests { } } - Thread::scoped(move|| { + thread::spawn(move|| { drop(S1); }).join().ok().unwrap(); } @@ -677,7 +677,7 @@ mod tests { } } - Thread::scoped(move|| unsafe { + thread::spawn(move|| unsafe { K1.with(|s| *s.get() = Some(S1)); }).join().ok().unwrap(); } @@ -704,7 +704,7 @@ mod tests { } let (tx, rx) = channel(); - let _t = Thread::spawn(move|| unsafe { + let _t = thread::spawn(move|| unsafe { let mut tx = Some(tx); K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); }); diff --git a/src/libstd/thunk.rs b/src/libstd/thunk.rs index 0831242f954..fe39954f0d4 100644 --- a/src/libstd/thunk.rs +++ b/src/libstd/thunk.rs @@ -16,21 +16,24 @@ use alloc::boxed::Box; use core::marker::Send; use core::ops::FnOnce; -pub struct Thunk<A=(),R=()> { - invoke: Box<Invoke<A,R>+Send> +pub struct Thunk<'a, A=(),R=()> { + #[cfg(stage0)] + invoke: Box<Invoke<A,R>+Send>, + #[cfg(not(stage0))] + invoke: Box<Invoke<A,R>+Send + 'a>, } -impl<R> Thunk<(),R> { - pub fn new<F>(func: F) -> Thunk<(),R> - where F : FnOnce() -> R, F : Send +impl<'a, R> Thunk<'a,(),R> { + pub fn new<F>(func: F) -> Thunk<'a,(),R> + where F : FnOnce() -> R, F : Send + 'a { Thunk::with_arg(move|()| func()) } } -impl<A,R> Thunk<A,R> { - pub fn with_arg<F>(func: F) -> Thunk<A,R> - where F : FnOnce(A) -> R, F : Send +impl<'a,A,R> Thunk<'a,A,R> { + pub fn with_arg<F>(func: F) -> Thunk<'a,A,R> + where F : FnOnce(A) -> R, F : Send + 'a { Thunk { invoke: box func |
