about summary refs log tree commit diff
path: root/src/libstd/sync
diff options
context:
space:
mode:
authorAaron Turon <aturon@mozilla.com>2014-12-14 00:05:32 -0800
committerAaron Turon <aturon@mozilla.com>2014-12-18 23:31:52 -0800
commita27fbac86849e07a0a6c746869d8f78319bd3a16 (patch)
treef17d75fcdd4d353f5ff919e491a5fc71252c0ef1 /src/libstd/sync
parent13f302d0c5dd3a88426da53ba07cdbe16459635b (diff)
Revise std::thread API to join by default
This commit is part of a series that introduces a `std::thread` API to
replace `std::task`.

In the new API, `spawn` returns a `JoinGuard`, which by default will
join the spawned thread when dropped. It can also be used to join
explicitly at any time, returning the thread's result. Alternatively,
the spawned thread can be explicitly detached (so no join takes place).

As part of this change, Rust processes now terminate when the main
thread exits, even if other detached threads are still running, moving
Rust closer to standard threading models. This new behavior may break code
that was relying on the previously implicit join-all.

In addition to the above, the new thread API also offers some built-in
support for building blocking abstractions in user space; see the module
doc for details.

Closes #18000

[breaking-change]
Diffstat (limited to 'src/libstd/sync')
-rw-r--r--src/libstd/sync/atomic.rs10
-rw-r--r--src/libstd/sync/barrier.rs5
-rw-r--r--src/libstd/sync/condvar.rs6
-rw-r--r--src/libstd/sync/future.rs2
-rw-r--r--src/libstd/sync/mutex.rs9
-rw-r--r--src/libstd/sync/rwlock.rs18
-rw-r--r--src/libstd/sync/task_pool.rs2
7 files changed, 26 insertions, 26 deletions
diff --git a/src/libstd/sync/atomic.rs b/src/libstd/sync/atomic.rs
index fe5b962fa4b..26778ef70b3 100644
--- a/src/libstd/sync/atomic.rs
+++ b/src/libstd/sync/atomic.rs
@@ -42,14 +42,15 @@
 //! ```
 //! use std::sync::Arc;
 //! use std::sync::atomic::{AtomicUint, SeqCst};
+//! use std::thread::Thread;
 //!
 //! fn main() {
 //!     let spinlock = Arc::new(AtomicUint::new(1));
 //!
 //!     let spinlock_clone = spinlock.clone();
-//!     spawn(move|| {
+//!     Thread::spawn(move|| {
 //!         spinlock_clone.store(0, SeqCst);
-//!     });
+//!     }).detach();
 //!
 //!     // Wait for the other task to release the lock
 //!     while spinlock.load(SeqCst) != 0 {}
@@ -61,6 +62,7 @@
 //! ```
 //! use std::sync::Arc;
 //! use std::sync::atomic::{AtomicOption, SeqCst};
+//! use std::thread::Thread;
 //!
 //! fn main() {
 //!     struct BigObject;
@@ -68,14 +70,14 @@
 //!     let shared_big_object = Arc::new(AtomicOption::empty());
 //!
 //!     let shared_big_object_clone = shared_big_object.clone();
-//!     spawn(move|| {
+//!     Thread::spawn(move|| {
 //!         let unwrapped_big_object = shared_big_object_clone.take(SeqCst);
 //!         if unwrapped_big_object.is_some() {
 //!             println!("got a big object from another task");
 //!         } else {
 //!             println!("other task hasn't sent big object yet");
 //!         }
-//!     });
+//!     }).detach();
 //!
 //!     shared_big_object.swap(box BigObject, SeqCst);
 //! }
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index 1b8574604a0..6573d9273ce 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -15,17 +15,18 @@ use sync::{Mutex, Condvar};
 ///
 /// ```rust
 /// use std::sync::{Arc, Barrier};
+/// use std::thread::Thread;
 ///
 /// let barrier = Arc::new(Barrier::new(10));
 /// for _ in range(0u, 10) {
 ///     let c = barrier.clone();
 ///     // The same messages will be printed together.
 ///     // You will NOT see any interleaving.
-///     spawn(move|| {
+///     Thread::spawn(move|| {
 ///         println!("before wait");
 ///         c.wait();
 ///         println!("after wait");
-///     });
+///     }).detach();
 /// }
 /// ```
 pub struct Barrier {
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 3bdab261e19..be27c06b83c 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -36,17 +36,18 @@ use time::Duration;
 ///
 /// ```
 /// use std::sync::{Arc, Mutex, Condvar};
+/// use std::thread::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
-/// spawn(move|| {
+/// Thread::spawn(move|| {
 ///     let &(ref lock, ref cvar) = &*pair2;
 ///     let mut started = lock.lock();
 ///     *started = true;
 ///     cvar.notify_one();
-/// });
+/// }).detach();
 ///
 /// // wait for the thread to start up
 /// let &(ref lock, ref cvar) = &*pair;
@@ -362,4 +363,3 @@ mod tests {
 
     }
 }
-
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index 16f2cff5998..5e9d234c642 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -142,7 +142,7 @@ impl<A:Send> Future<A> {
         Thread::spawn(move |:| {
             // Don't panic if the other end has hung up
             let _ = tx.send_opt(blk());
-        });
+        }).detach();
 
         Future::from_receiver(rx)
     }
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index fc73e2957a5..4829be569cc 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -35,6 +35,7 @@ use sys_common::mutex as sys;
 ///
 /// ```rust
 /// use std::sync::{Arc, Mutex};
+/// use std::thread::Thread;
 /// const N: uint = 10;
 ///
 /// // Spawn a few threads to increment a shared variable (non-atomically), and
@@ -47,7 +48,7 @@ use sys_common::mutex as sys;
 /// let (tx, rx) = channel();
 /// for _ in range(0u, 10) {
 ///     let (data, tx) = (data.clone(), tx.clone());
-///     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.
@@ -57,7 +58,7 @@ use sys_common::mutex as sys;
 ///             tx.send(());
 ///         }
 ///         // the lock is unlocked here when `data` goes out of scope.
-///     });
+///     }).detach();
 /// }
 ///
 /// rx.recv();
@@ -386,7 +387,7 @@ mod test {
     fn test_mutex_arc_poison() {
         let arc = Arc::new(Mutex::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.lock();
             assert_eq!(*lock, 2);
         }).join();
@@ -414,7 +415,7 @@ mod test {
     fn test_mutex_arc_access_in_unwind() {
         let arc = Arc::new(Mutex::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join::<()>(move|| -> () {
+        let _ = Thread::spawn(move|| -> () {
             struct Unwinder {
                 i: Arc<Mutex<int>>,
             }
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 1f1e9eea1d6..07b2f2cf541 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -409,7 +409,7 @@ mod tests {
     fn test_rw_arc_poison_wr() {
         let arc = Arc::new(RWLock::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.write();
             assert_eq!(*lock, 2);
         }).join();
@@ -422,7 +422,7 @@ mod tests {
     fn test_rw_arc_poison_ww() {
         let arc = Arc::new(RWLock::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.write();
             assert_eq!(*lock, 2);
         }).join();
@@ -434,7 +434,7 @@ mod tests {
     fn test_rw_arc_no_poison_rr() {
         let arc = Arc::new(RWLock::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.read();
             assert_eq!(*lock, 2);
         }).join();
@@ -445,7 +445,7 @@ mod tests {
     fn test_rw_arc_no_poison_rw() {
         let arc = Arc::new(RWLock::new(1i));
         let arc2 = arc.clone();
-        let _ = Thread::with_join(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.read();
             assert_eq!(*lock, 2);
         }).join();
@@ -468,13 +468,13 @@ mod tests {
                 *lock = tmp + 1;
             }
             tx.send(());
-        });
+        }).detach();
 
         // Readers try to catch the writer in the act
         let mut children = Vec::new();
         for _ in range(0u, 5) {
             let arc3 = arc.clone();
-            children.push(Thread::with_join(move|| {
+            children.push(Thread::spawn(move|| {
                 let lock = arc3.read();
                 assert!(*lock >= 0);
             }));
@@ -495,11 +495,7 @@ mod tests {
     fn test_rw_arc_access_in_unwind() {
         let arc = Arc::new(RWLock::new(1i));
         let arc2 = arc.clone();
-<<<<<<< HEAD
-        let _ = task::try(move|| -> () {
-=======
-        let _ = Thread::with_join::<()>(proc() {
->>>>>>> Fallout from new thread API
+        let _ = Thread::spawn(move|| -> () {
             struct Unwinder {
                 i: Arc<RWLock<int>>,
             }
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index 5e7944d5fe5..793825f1b08 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -126,7 +126,7 @@ fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
         }
 
         sentinel.cancel();
-    });
+    }).detach();
 }
 
 #[cfg(test)]