about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-15 01:05:03 +0000
committerbors <bors@rust-lang.org>2015-04-15 01:05:03 +0000
commit16e1fcead14628701e1b10b9d00c898d748db2ed (patch)
tree37d18d85fa9631880c287c3795d5b4b3d8994f20 /src/libstd/thread
parent8415fa27877a4309a79b08c75a52eb4c3546b7a5 (diff)
parente053571df21fda7bb909c1b79de9b0cbe1a2931d (diff)
downloadrust-16e1fcead14628701e1b10b9d00c898d748db2ed.tar.gz
rust-16e1fcead14628701e1b10b9d00c898d748db2ed.zip
Auto merge of #24433 - alexcrichton:rollup, r=alexcrichton
Diffstat (limited to 'src/libstd/thread')
-rw-r--r--src/libstd/thread/local.rs2
-rw-r--r--src/libstd/thread/mod.rs96
-rw-r--r--src/libstd/thread/scoped_tls.rs4
3 files changed, 63 insertions, 39 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index f5a1093be2b..cc4031cc180 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -226,7 +226,7 @@ pub enum LocalKeyState {
 }
 
 impl<T: 'static> LocalKey<T> {
-    /// Acquire a reference to the value in this TLS key.
+    /// Acquires a reference to the value in this TLS key.
     ///
     /// This will lazily initialize the value if this thread has not referenced
     /// this key yet.
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 0e5fee27ffe..4fd0340f09a 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -67,13 +67,33 @@
 //! thread. This means that it can outlive its parent (the thread that spawned
 //! it), unless this parent is the main thread.
 //!
+//! The parent thread can also wait on the completion of the child
+//! thread; a call to `spawn` produces a `JoinHandle`, which provides
+//! a `join` method for waiting:
+//!
+//! ```rust
+//! use std::thread;
+//!
+//! let child = thread::spawn(move || {
+//!     // some work here
+//! });
+//! // some work here
+//! let res = child.join();
+//! ```
+//!
+//! The `join` method returns a `Result` containing `Ok` of the final
+//! value produced by the child thread, or `Err` of the value given to
+//! a call to `panic!` if the child panicked.
+//!
 //! ## Scoped threads
 //!
-//! Often a parent thread uses a child thread to perform some particular task,
-//! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `thread::scoped` function:
+//! The `spawn` method does not allow the child and parent threads to
+//! share any stack data, since that is not safe in general. However,
+//! `scoped` makes it possible to share the parent's stack by forcing
+//! a join before any relevant stack frames are popped:
 //!
 //! ```rust
+//! # #![feature(scoped)]
 //! use std::thread;
 //!
 //! let guard = thread::scoped(move || {
@@ -215,7 +235,7 @@ pub struct Builder {
 }
 
 impl Builder {
-    /// Generate the base configuration for spawning a thread, from which
+    /// Generates the base configuration for spawning a thread, from which
     /// configuration methods can be chained.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> Builder {
@@ -225,7 +245,7 @@ impl Builder {
         }
     }
 
-    /// Name the thread-to-be. Currently the name is used for identification
+    /// Names the thread-to-be. Currently the name is used for identification
     /// only in panic messages.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn name(mut self, name: String) -> Builder {
@@ -233,14 +253,14 @@ impl Builder {
         self
     }
 
-    /// Set the size of the stack for the new thread.
+    /// Sets the size of the stack for the new thread.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn stack_size(mut self, size: usize) -> Builder {
         self.stack_size = Some(size);
         self
     }
 
-    /// Spawn a new thread, and return a join handle for it.
+    /// Spawns a new thread, and returns 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
@@ -253,14 +273,14 @@ impl Builder {
     /// `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
+    pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
+        F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
     {
         self.spawn_inner(Box::new(f)).map(|i| JoinHandle(i))
     }
 
-    /// Spawn a new child thread that must be joined within a given
-    /// scope, and return a `JoinGuard`.
+    /// Spawns a new child thread that must be joined within a given
+    /// scope, and returns a `JoinGuard`.
     ///
     /// The join guard can be used to explicitly join the child thread (via
     /// `join`), returning `Result<T>`, or it will implicitly join the child
@@ -274,7 +294,8 @@ impl Builder {
     /// 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")]
+    #[unstable(feature = "scoped",
+               reason = "memory unsafe if destructor is avoided, see #24292")]
     pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
@@ -355,7 +376,7 @@ impl Builder {
 // Free functions
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Spawn a new thread, returning a `JoinHandle` for it.
+/// Spawns a new thread, returning a `JoinHandle` for it.
 ///
 /// The join handle will implicitly *detach* the child thread upon being
 /// dropped. In this case, the child thread may outlive the parent (unless
@@ -370,11 +391,13 @@ impl Builder {
 /// Panics 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 {
+pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
+    F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+{
     Builder::new().spawn(f).unwrap()
 }
 
-/// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
+/// Spawns 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
@@ -387,7 +410,8 @@ pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static {
 ///
 /// Panics if the OS fails to create a thread; use `Builder::scoped`
 /// to recover from such errors.
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "scoped",
+           reason = "memory unsafe if destructor is avoided, see #24292")]
 pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
     T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
 {
@@ -400,7 +424,7 @@ pub fn current() -> Thread {
     thread_info::current_thread()
 }
 
-/// Cooperatively give up a timeslice to the OS scheduler.
+/// Cooperatively gives up a timeslice to the OS scheduler.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn yield_now() {
     unsafe { imp::yield_now() }
@@ -413,7 +437,7 @@ pub fn panicking() -> bool {
     unwind::panicking()
 }
 
-/// Invoke a closure, capturing the cause of panic if one occurs.
+/// Invokes a closure, capturing the cause of panic if one occurs.
 ///
 /// This function will return `Ok(())` if the closure does not panic, and will
 /// return `Err(cause)` if the closure panics. The `cause` returned is the
@@ -462,7 +486,7 @@ pub fn catch_panic<F, R>(f: F) -> Result<R>
     Ok(result.unwrap())
 }
 
-/// Put the current thread to sleep for the specified amount of time.
+/// Puts the current thread to sleep for the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
 /// specifics or platform-dependent functionality. Note that on unix platforms
@@ -482,7 +506,7 @@ pub fn sleep(dur: Duration) {
     imp::sleep(dur)
 }
 
-/// Block unless or until the current thread's token is made available (may wake spuriously).
+/// Blocks unless or until the current thread's token is made available (may wake spuriously).
 ///
 /// See the module doc for more detail.
 //
@@ -501,7 +525,7 @@ pub fn park() {
     *guard = false;
 }
 
-/// Block unless or until the current thread's token is made available or
+/// Blocks 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
@@ -573,7 +597,7 @@ impl Thread {
         }
     }
 
-    /// Get the thread's name.
+    /// Gets the thread's name.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn name(&self) -> Option<&str> {
         self.inner.name.as_ref().map(|s| &**s)
@@ -635,27 +659,28 @@ impl<T> JoinInner<T> {
 /// handle: the ability to join a child thread is a uniquely-owned
 /// permission.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct JoinHandle(JoinInner<()>);
+pub struct JoinHandle<T>(JoinInner<T>);
 
-impl JoinHandle {
-    /// Extract a handle to the underlying thread
+impl<T> JoinHandle<T> {
+    /// Extracts 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.
+    /// Waits 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<()> {
+    pub fn join(mut self) -> Result<T> {
         self.0.join()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Drop for JoinHandle {
+#[unsafe_destructor]
+impl<T> Drop for JoinHandle<T> {
     fn drop(&mut self) {
         if !self.0.joined {
             unsafe { imp::detach(self.0.native) }
@@ -674,7 +699,8 @@ impl Drop for JoinHandle {
 /// handle: the ability to join a child thread is a uniquely-owned
 /// permission.
 #[must_use = "thread will be immediately joined if `JoinGuard` is not used"]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "scoped",
+           reason = "memory unsafe if destructor is avoided, see #24292")]
 pub struct JoinGuard<'a, T: Send + 'a> {
     inner: JoinInner<T>,
     _marker: PhantomData<&'a T>,
@@ -684,13 +710,13 @@ pub struct JoinGuard<'a, T: Send + 'a> {
 unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {}
 
 impl<'a, T: Send + 'a> JoinGuard<'a, T> {
-    /// Extract a handle to the thread this guard will join on.
+    /// Extracts a handle to the thread this guard will join on.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn thread(&self) -> &Thread {
         &self.inner.thread
     }
 
-    /// Wait for the associated thread to finish, returning the result of the
+    /// Waits for the associated thread to finish, returning the result of the
     /// thread's calculation.
     ///
     /// # Panics
@@ -706,7 +732,8 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> {
 }
 
 #[unsafe_destructor]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "scoped",
+           reason = "memory unsafe if destructor is avoided, see #24292")]
 impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
     fn drop(&mut self) {
         if !self.inner.joined {
@@ -728,7 +755,6 @@ mod test {
     use any::Any;
     use sync::mpsc::{channel, Sender};
     use result;
-    use std::old_io::{ChanReader, ChanWriter};
     use super::{Builder};
     use thread;
     use thunk::Thunk;
@@ -967,13 +993,11 @@ mod test {
 
     #[test]
     fn test_park_timeout_unpark_called_other_thread() {
-        use std::old_io;
-
         for _ in 0..10 {
             let th = thread::current();
 
             let _guard = thread::spawn(move || {
-                old_io::timer::sleep(Duration::milliseconds(50));
+                super::sleep_ms(50);
                 th.unpark();
             });
 
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
index fa980954c2f..9c0b4a5d833 100644
--- a/src/libstd/thread/scoped_tls.rs
+++ b/src/libstd/thread/scoped_tls.rs
@@ -135,7 +135,7 @@ macro_rules! __scoped_thread_local_inner {
            reason = "scoped TLS has yet to have wide enough use to fully consider \
                      stabilizing its interface")]
 impl<T> ScopedKey<T> {
-    /// Insert a value into this scoped thread local storage slot for a
+    /// Inserts a value into this scoped thread local storage slot for a
     /// duration of a closure.
     ///
     /// While `cb` is running, the value `t` will be returned by `get` unless
@@ -188,7 +188,7 @@ impl<T> ScopedKey<T> {
         cb()
     }
 
-    /// Get a value out of this scoped variable.
+    /// Gets a value out of this scoped variable.
     ///
     /// This function takes a closure which receives the value of this
     /// variable.