diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 8a27903259f92..f8e2ba4828f38 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -447,7 +447,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { loop { //waiting 1 second for gdbserver start timer::sleep(Duration::milliseconds(1000)); - let result = Thread::spawn(move || { + let result = Thread::scoped(move || { tcp::TcpStream::connect("127.0.0.1:5039").unwrap(); }).join(); if result.is_err() { diff --git a/src/doc/intro.md b/src/doc/intro.md index a4e9d85bffdf8..fbc96a577a41a 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -395,7 +395,7 @@ fn main() { for _ in range(0u, 10u) { Thread::spawn(move || { println!("Hello, world!"); - }).detach(); + }); } } ``` @@ -405,8 +405,7 @@ This program creates ten threads, who all print `Hello, world!`. The double bars `||`. (The `move` keyword indicates that the closure takes ownership of any data it uses; we'll have more on the significance of this shortly.) This closure is executed in a new thread created by -`spawn`. The `detach` method means that the child thread is allowed to -outlive its parent. +`spawn`. One common form of problem in concurrent programs is a 'data race.' This occurs when two different threads attempt to access the same @@ -429,7 +428,7 @@ fn main() { for i in range(0u, 3u) { Thread::spawn(move || { for j in range(0, 3) { numbers[j] += 1 } - }).detach(); + }); } } ``` @@ -488,7 +487,7 @@ fn main() { (*array)[i] += 1; println!("numbers[{}] is {}", i, (*array)[i]); - }).detach(); + }); } } ``` diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index f19ec765fbe6c..e78f94f79cc93 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -42,7 +42,7 @@ //! //! Thread::spawn(move || { //! println!("{}", five); -//! }).detach(); +//! }); //! } //! ``` //! @@ -63,7 +63,7 @@ //! *number += 1; //! //! println!("{}", *number); // prints 6 -//! }).detach(); +//! }); //! } //! ``` @@ -106,7 +106,7 @@ use heap::deallocate; /// let local_numbers = child_numbers.as_slice(); /// /// // Work with the local numbers -/// }).detach(); +/// }); /// } /// } /// ``` diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 4ebd3dc63b698..cbf610663e4cc 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -924,7 +924,7 @@ mod tests { #[test] fn test_send() { let n = list_from(&[1i,2,3]); - Thread::spawn(move || { + Thread::scoped(move || { check_links(&n); let a: &[_] = &[&1,&2,&3]; assert_eq!(a, n.iter().collect::>()); diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index aee1d825bc240..e740a9292528c 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -50,7 +50,7 @@ //! let spinlock_clone = spinlock.clone(); //! Thread::spawn(move|| { //! spinlock_clone.store(0, Ordering::SeqCst); -//! }).detach(); +//! }); //! //! // Wait for the other task to release the lock //! while spinlock.load(Ordering::SeqCst) != 0 {} diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 4164a8551cc3c..5af114abeea77 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -543,7 +543,7 @@ pub fn monitor(f: F) { cfg = cfg.stack_size(STACK_SIZE); } - match cfg.spawn(move || { std::io::stdio::set_stderr(box w); f() }).join() { + match cfg.scoped(move || { std::io::stdio::set_stderr(box w); f() }).join() { Ok(()) => { /* fallthrough */ } Err(value) => { // Thread panicked without emitting a fatal diagnostic diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 452e81e2e0e6c..f0de96141faf3 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -928,7 +928,7 @@ fn run_work_multithreaded(sess: &Session, } tx.take().unwrap().send(()).unwrap(); - }).detach(); + }); } let mut panicked = false; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e0c778af045fe..ee65ef0662305 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -103,7 +103,7 @@ struct Output { pub fn main() { static STACK_SIZE: uint = 32000000; // 32MB - let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || { + let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || { main_args(std::os::args().as_slice()) }).join(); std::os::set_exit_status(res.map_err(|_| ()).unwrap()); @@ -345,7 +345,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche let cr = Path::new(cratefile); info!("starting to run rustc"); - let (mut krate, analysis) = std::thread::Thread::spawn(move |:| { + let (mut krate, analysis) = std::thread::Thread::scoped(move |:| { let cr = cr; core::run_core(paths, cfgs, externs, &cr, triple) }).join().map_err(|_| "rustc failed").unwrap(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9d39b463bdd76..bbe35eb0e9ccc 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -157,7 +157,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, None => box io::stderr() as Box, }; io::util::copy(&mut p, &mut err).unwrap(); - }).detach(); + }); let emitter = diagnostic::EmitterWriter::new(box w2, None); // Compile the code diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index bcd0c09b77d61..bce097e17ef0f 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -173,7 +173,7 @@ mod test { tx.send(vec![3u8, 4u8]).unwrap(); tx.send(vec![5u8, 6u8]).unwrap(); tx.send(vec![7u8, 8u8]).unwrap(); - }).detach(); + }); let mut reader = ChanReader::new(rx); let mut buf = [0u8; 3]; @@ -216,7 +216,7 @@ mod test { tx.send(b"rld\nhow ".to_vec()).unwrap(); tx.send(b"are you?".to_vec()).unwrap(); tx.send(b"".to_vec()).unwrap(); - }).detach(); + }); let mut reader = ChanReader::new(rx); @@ -235,7 +235,7 @@ mod test { writer.write_be_u32(42).unwrap(); let wanted = vec![0u8, 0u8, 0u8, 42u8]; - let got = match Thread::spawn(move|| { rx.recv().unwrap() }).join() { + let got = match Thread::scoped(move|| { rx.recv().unwrap() }).join() { Ok(got) => got, Err(_) => panic!(), }; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 42f72fa32597e..9ef9081bc3c84 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -120,10 +120,12 @@ //! for stream in acceptor.incoming() { //! match stream { //! Err(e) => { /* connection failed */ } -//! Ok(stream) => Thread::spawn(move|| { -//! // connection succeeded -//! handle_client(stream) -//! }).detach() +//! Ok(stream) => { +//! Thread::spawn(move|| { +//! // connection succeeded +//! handle_client(stream) +//! }); +//! } //! } //! } //! diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs index 738c70412f78a..29295b5751cd4 100644 --- a/src/libstd/io/net/pipe.rs +++ b/src/libstd/io/net/pipe.rs @@ -608,7 +608,7 @@ mod tests { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv(); - }).detach(); + }); let mut b = [0]; let mut s = UnixStream::connect(&addr).unwrap(); @@ -645,7 +645,7 @@ mod tests { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv(); - }).detach(); + }); let mut s = UnixStream::connect(&addr).unwrap(); let s2 = s.clone(); @@ -672,7 +672,7 @@ mod tests { rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_timeout(Some(20)); @@ -716,7 +716,7 @@ mod tests { } } let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_read_timeout(Some(20)); @@ -739,7 +739,7 @@ mod tests { rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_write_timeout(Some(20)); @@ -766,7 +766,7 @@ mod tests { rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); let s2 = s.clone(); diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index 3e59aaa05efd2..b1762ff26fc6a 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -146,7 +146,7 @@ impl TcpStream { /// timer::sleep(Duration::seconds(1)); /// let mut stream = stream2; /// stream.close_read(); - /// }).detach(); + /// }); /// /// // wait for some data, will get canceled after one second /// let mut buf = [0]; @@ -295,10 +295,12 @@ impl sys_common::AsInner for TcpStream { /// for stream in acceptor.incoming() { /// match stream { /// Err(e) => { /* connection failed */ } -/// Ok(stream) => Thread::spawn(move|| { -/// // connection succeeded -/// handle_client(stream) -/// }).detach() +/// Ok(stream) => { +/// Thread::spawn(move|| { +/// // connection succeeded +/// handle_client(stream) +/// }); +/// } /// } /// } /// @@ -432,7 +434,7 @@ impl TcpAcceptor { /// Err(e) => panic!("unexpected error: {}", e), /// } /// } - /// }).detach(); + /// }); /// /// # fn wait_for_sigint() {} /// // Now that our accept loop is running, wait for the program to be @@ -1186,7 +1188,7 @@ mod test { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv().unwrap(); - }).detach(); + }); let mut b = [0]; let mut s = TcpStream::connect(addr).unwrap(); @@ -1223,7 +1225,7 @@ mod test { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv().unwrap(); - }).detach(); + }); let mut s = TcpStream::connect(addr).unwrap(); let s2 = s.clone(); @@ -1250,7 +1252,7 @@ mod test { rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_timeout(Some(20)); @@ -1289,7 +1291,7 @@ mod test { } } let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_read_timeout(Some(20)); @@ -1312,7 +1314,7 @@ mod test { rx.recv().unwrap(); assert!(s.write(&[0]).is_ok()); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); s.set_write_timeout(Some(20)); @@ -1340,7 +1342,7 @@ mod test { rx.recv().unwrap(); assert_eq!(s.write(&[0]), Ok(())); let _ = rx.recv(); - }).detach(); + }); let mut s = a.accept().unwrap(); let s2 = s.clone(); diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index efb573416208e..55df6330dd33c 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -720,7 +720,7 @@ impl Process { Thread::spawn(move |:| { let mut stream = stream; tx.send(stream.read_to_end()).unwrap(); - }).detach(); + }); } None => tx.send(Ok(Vec::new())).unwrap() } diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index e073f76af825c..8a0445be47135 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -358,7 +358,7 @@ mod test { Thread::spawn(move|| { let _ = timer_rx.recv(); - }).detach(); + }); // when we drop the TimerWatcher we're going to destroy the channel, // which must wake up the task on the other end @@ -372,7 +372,7 @@ mod test { Thread::spawn(move|| { let _ = timer_rx.recv(); - }).detach(); + }); timer.oneshot(Duration::milliseconds(1)); } @@ -385,7 +385,7 @@ mod test { Thread::spawn(move|| { let _ = timer_rx.recv(); - }).detach(); + }); timer.sleep(Duration::milliseconds(1)); } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index be3e49c0b824c..43f86033da084 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -303,8 +303,8 @@ macro_rules! try { /// # fn long_running_task() {} /// # fn calculate_the_answer() -> int { 42i } /// -/// Thread::spawn(move|| { long_running_task(); tx1.send(()) }).detach(); -/// Thread::spawn(move|| { tx2.send(calculate_the_answer()) }).detach(); +/// 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/path/posix.rs b/src/libstd/path/posix.rs index a307132810e4c..805f45c61c1fc 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -510,17 +510,17 @@ mod tests { #[test] fn test_null_byte() { use thread::Thread; - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { Path::new(b"foo/bar\0") }).join(); assert!(result.is_err()); - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { Path::new("test").set_filename(b"f\0o") }).join(); assert!(result.is_err()); - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { Path::new("test").push(b"f\0o"); }).join(); assert!(result.is_err()); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index ff269b734765a..bd3382b428885 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1298,17 +1298,17 @@ mod tests { #[test] fn test_null_byte() { use thread::Thread; - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { Path::new(b"foo/bar\0") }).join(); assert!(result.is_err()); - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { Path::new("test").set_filename(b"f\0o") }).join(); assert!(result.is_err()); - let result = Thread::spawn(move || { + let result = Thread::scoped(move || { Path::new("test").push(b"f\0o"); }).join(); assert!(result.is_err()); diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index e697a1adeb5bd..18d40ecd3ebe5 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -394,7 +394,7 @@ mod test { r.fill_bytes(&mut v); Thread::yield_now(); } - }).detach(); + }); } // start all the tasks diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index bf5da3e7cbae0..7093987940038 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -26,7 +26,7 @@ use sync::{Mutex, Condvar}; /// println!("before wait"); /// c.wait(); /// println!("after wait"); -/// }).detach(); +/// }); /// } /// ``` #[stable] @@ -126,7 +126,7 @@ mod tests { let tx = tx.clone(); Thread::spawn(move|| { tx.send(c.wait().is_leader()).unwrap(); - }).detach(); + }); } // At this point, all spawned tasks should be blocked, diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index e97be51fdbc25..3c0ae71255dbe 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -48,7 +48,7 @@ use sync::{mutex, MutexGuard}; /// let mut started = lock.lock().unwrap(); /// *started = true; /// cvar.notify_one(); -/// }).detach(); +/// }); /// /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; @@ -338,7 +338,7 @@ mod tests { cnt = cond.wait(cnt).unwrap(); } tx.send(()).unwrap(); - }).detach(); + }); } drop(tx); diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index 4c6adcc04f67c..568c24446e7a3 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -141,7 +141,7 @@ impl Future { Thread::spawn(move |:| { // Don't panic if the other end has hung up let _ = tx.send(blk()); - }).detach(); + }); Future::from_receiver(rx) } diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 5dc58add665fd..f24a329a390a5 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -60,7 +60,7 @@ //! let (tx, rx) = channel(); //! Thread::spawn(move|| { //! tx.send(10i).unwrap(); -//! }).detach(); +//! }); //! assert_eq!(rx.recv().unwrap(), 10i); //! ``` //! @@ -78,7 +78,7 @@ //! let tx = tx.clone(); //! Thread::spawn(move|| { //! tx.send(i).unwrap(); -//! }).detach() +//! }); //! } //! //! for _ in range(0i, 10i) { @@ -109,7 +109,7 @@ //! Thread::spawn(move|| { //! // This will wait for the parent task to start receiving //! tx.send(53).unwrap(); -//! }).detach(); +//! }); //! rx.recv().unwrap(); //! ``` //! @@ -476,7 +476,7 @@ impl UnsafeFlavor for Receiver { /// Thread::spawn(move|| { /// # fn expensive_computation() {} /// tx.send(expensive_computation()).unwrap(); -/// }).detach(); +/// }); /// /// // Do some useful work for awhile /// @@ -518,7 +518,7 @@ pub fn channel() -> (Sender, Receiver) { /// Thread::spawn(move|| { /// // this will block until the previous message has been received /// tx.send(2i).unwrap(); -/// }).detach(); +/// }); /// /// assert_eq!(rx.recv().unwrap(), 1i); /// assert_eq!(rx.recv().unwrap(), 2i); @@ -1144,7 +1144,7 @@ mod test { #[test] fn stress() { let (tx, rx) = channel::(); - let t = Thread::spawn(move|| { + let t = Thread::scoped(move|| { for _ in range(0u, 10000) { tx.send(1i).unwrap(); } }); for _ in range(0u, 10000) { @@ -1159,7 +1159,7 @@ mod test { static NTHREADS: uint = 8; let (tx, rx) = channel::(); - let t = Thread::spawn(move|| { + let t = Thread::scoped(move|| { for _ in range(0, AMT * NTHREADS) { assert_eq!(rx.recv().unwrap(), 1); } @@ -1173,7 +1173,7 @@ mod test { let tx = tx.clone(); Thread::spawn(move|| { for _ in range(0, AMT) { tx.send(1).unwrap(); } - }).detach(); + }); } drop(tx); t.join().ok().unwrap(); @@ -1183,14 +1183,14 @@ mod test { fn send_from_outside_runtime() { let (tx1, rx1) = channel::<()>(); let (tx2, rx2) = channel::(); - let t1 = Thread::spawn(move|| { + let t1 = Thread::scoped(move|| { tx1.send(()).unwrap(); for _ in range(0i, 40) { assert_eq!(rx2.recv().unwrap(), 1); } }); rx1.recv().unwrap(); - let t2 = Thread::spawn(move|| { + let t2 = Thread::scoped(move|| { for _ in range(0i, 40) { tx2.send(1).unwrap(); } @@ -1202,7 +1202,7 @@ mod test { #[test] fn recv_from_outside_runtime() { let (tx, rx) = channel::(); - let t = Thread::spawn(move|| { + let t = Thread::scoped(move|| { for _ in range(0i, 40) { assert_eq!(rx.recv().unwrap(), 1); } @@ -1217,11 +1217,11 @@ mod test { fn no_runtime() { let (tx1, rx1) = channel::(); let (tx2, rx2) = channel::(); - let t1 = Thread::spawn(move|| { + let t1 = Thread::scoped(move|| { assert_eq!(rx1.recv().unwrap(), 1); tx2.send(2).unwrap(); }); - let t2 = Thread::spawn(move|| { + let t2 = Thread::scoped(move|| { tx1.send(1).unwrap(); assert_eq!(rx2.recv().unwrap(), 2); }); @@ -1254,7 +1254,7 @@ mod test { #[test] fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { let (tx, rx) = channel::(); drop(tx); rx.recv().unwrap(); @@ -1336,7 +1336,7 @@ mod test { let _t = Thread::spawn(move|| { drop(tx); }); - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { assert!(rx.recv().unwrap() == box 10); }).join(); assert!(res.is_err()); @@ -1360,7 +1360,7 @@ mod test { let _t = Thread::spawn(move|| { drop(rx); }); - let _ = Thread::spawn(move|| { + let _ = Thread::scoped(move|| { tx.send(1).unwrap(); }).join(); } @@ -1371,15 +1371,15 @@ mod test { for _ in range(0, stress_factor()) { let (tx, rx) = channel::(); Thread::spawn(move|| { - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { rx.recv().unwrap(); }).join(); assert!(res.is_err()); - }).detach(); + }); let _t = Thread::spawn(move|| { Thread::spawn(move|| { drop(tx); - }).detach(); + }); }); } } @@ -1409,7 +1409,7 @@ mod test { Thread::spawn(move|| { tx.send(box i).unwrap(); send(tx, i + 1); - }).detach(); + }); } fn recv(rx: Receiver>, i: int) { @@ -1418,7 +1418,7 @@ mod test { Thread::spawn(move|| { assert!(rx.recv().unwrap() == box i); recv(rx, i + 1); - }).detach(); + }); } } } @@ -1439,7 +1439,7 @@ mod test { let tx = tx.clone(); Thread::spawn(move|| { tx.send(()).unwrap(); - }).detach(); + }); } for _ in range(0, total) { @@ -1644,7 +1644,7 @@ mod sync_tests { Thread::spawn(move|| { tx.send(1).unwrap(); tx.send(1).unwrap(); - }).detach(); + }); while rx.recv().is_ok() {} } @@ -1653,7 +1653,7 @@ mod sync_tests { let (tx, rx) = sync_channel::(0); Thread::spawn(move|| { for _ in range(0u, 10000) { tx.send(1).unwrap(); } - }).detach(); + }); for _ in range(0u, 10000) { assert_eq!(rx.recv().unwrap(), 1); } @@ -1675,13 +1675,13 @@ mod sync_tests { _ => {} } dtx.send(()).unwrap(); - }).detach(); + }); for _ in range(0, NTHREADS) { let tx = tx.clone(); Thread::spawn(move|| { for _ in range(0, AMT) { tx.send(1).unwrap(); } - }).detach(); + }); } drop(tx); drx.recv().unwrap(); @@ -1712,7 +1712,7 @@ mod sync_tests { #[test] fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { let (tx, rx) = sync_channel::(0); drop(tx); rx.recv().unwrap(); @@ -1800,7 +1800,7 @@ mod sync_tests { let _t = Thread::spawn(move|| { drop(tx); }); - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { assert!(rx.recv().unwrap() == box 10); }).join(); assert!(res.is_err()); @@ -1824,7 +1824,7 @@ mod sync_tests { let _t = Thread::spawn(move|| { drop(rx); }); - let _ = Thread::spawn(move || { + let _ = Thread::scoped(move || { tx.send(1).unwrap(); }).join(); } @@ -1835,7 +1835,7 @@ mod sync_tests { for _ in range(0, stress_factor()) { let (tx, rx) = sync_channel::(0); let _t = Thread::spawn(move|| { - let res = Thread::spawn(move|| { + let res = Thread::scoped(move|| { rx.recv().unwrap(); }).join(); assert!(res.is_err()); @@ -1843,7 +1843,7 @@ mod sync_tests { let _t = Thread::spawn(move|| { Thread::spawn(move|| { drop(tx); - }).detach(); + }); }); } } @@ -1873,7 +1873,7 @@ mod sync_tests { Thread::spawn(move|| { tx.send(box i).unwrap(); send(tx, i + 1); - }).detach(); + }); } fn recv(rx: Receiver>, i: int) { @@ -1882,7 +1882,7 @@ mod sync_tests { Thread::spawn(move|| { assert!(rx.recv().unwrap() == box i); recv(rx, i + 1); - }).detach(); + }); } } } @@ -1903,7 +1903,7 @@ mod sync_tests { let tx = tx.clone(); Thread::spawn(move|| { tx.send(()).unwrap(); - }).detach(); + }); } for _ in range(0, total) { diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index 9ad24a5a11ec5..f8eae1322bf1f 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -188,7 +188,7 @@ mod tests { q.push(i); } tx.send(()).unwrap(); - }).detach(); + }); } let mut i = 0u; diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 9756d08619356..c1b55c6ff78db 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -75,7 +75,7 @@ use sys_common::mutex as sys; /// tx.send(()).unwrap(); /// } /// // the lock is unlocked here when `data` goes out of scope. -/// }).detach(); +/// }); /// } /// /// rx.recv().unwrap(); @@ -90,7 +90,7 @@ use sys_common::mutex as sys; /// let lock = Arc::new(Mutex::new(0u)); /// let lock2 = lock.clone(); /// -/// let _ = Thread::spawn(move || -> () { +/// let _ = Thread::scoped(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(); @@ -376,9 +376,9 @@ mod test { let (tx, rx) = channel(); for _ in range(0, K) { let tx2 = tx.clone(); - Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }).detach(); + Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); let tx2 = tx.clone(); - Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }).detach(); + Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }); } drop(tx); @@ -453,7 +453,7 @@ mod test { fn test_mutex_arc_poison() { let arc = Arc::new(Mutex::new(1i)); let arc2 = arc.clone(); - let _ = Thread::spawn(move|| { + let _ = Thread::scoped(move|| { let lock = arc2.lock().unwrap(); assert_eq!(*lock, 2); }).join(); @@ -480,7 +480,7 @@ mod test { fn test_mutex_arc_access_in_unwind() { let arc = Arc::new(Mutex::new(1i)); let arc2 = arc.clone(); - let _ = Thread::spawn(move|| -> () { + let _ = Thread::scoped(move|| -> () { struct Unwinder { i: Arc>, } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 15ca4783700f0..3bf2ae277e0df 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -159,7 +159,7 @@ mod test { assert!(run); } tx.send(()).unwrap(); - }).detach(); + }); } unsafe { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 36f9d4228b351..7db2111cc4629 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -411,7 +411,7 @@ mod tests { } } drop(tx); - }).detach(); + }); } drop(tx); let _ = rx.recv(); @@ -422,7 +422,7 @@ mod tests { fn test_rw_arc_poison_wr() { let arc = Arc::new(RwLock::new(1i)); let arc2 = arc.clone(); - let _: Result = Thread::spawn(move|| { + let _: Result = Thread::scoped(move|| { let _lock = arc2.write().unwrap(); panic!(); }).join(); @@ -433,7 +433,7 @@ mod tests { fn test_rw_arc_poison_ww() { let arc = Arc::new(RwLock::new(1i)); let arc2 = arc.clone(); - let _: Result = Thread::spawn(move|| { + let _: Result = Thread::scoped(move|| { let _lock = arc2.write().unwrap(); panic!(); }).join(); @@ -444,7 +444,7 @@ mod tests { fn test_rw_arc_no_poison_rr() { let arc = Arc::new(RwLock::new(1i)); let arc2 = arc.clone(); - let _: Result = Thread::spawn(move|| { + let _: Result = Thread::scoped(move|| { let _lock = arc2.read().unwrap(); panic!(); }).join(); @@ -455,7 +455,7 @@ mod tests { fn test_rw_arc_no_poison_rw() { let arc = Arc::new(RwLock::new(1i)); let arc2 = arc.clone(); - let _: Result = Thread::spawn(move|| { + let _: Result = Thread::scoped(move|| { let _lock = arc2.read().unwrap(); panic!() }).join(); @@ -478,13 +478,13 @@ mod tests { *lock = tmp + 1; } tx.send(()).unwrap(); - }).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::spawn(move|| { + children.push(Thread::scoped(move|| { let lock = arc3.read().unwrap(); assert!(*lock >= 0); })); @@ -505,7 +505,7 @@ mod tests { fn test_rw_arc_access_in_unwind() { let arc = Arc::new(RwLock::new(1i)); let arc2 = arc.clone(); - let _ = Thread::spawn(move|| -> () { + let _ = Thread::scoped(move|| -> () { struct Unwinder { i: Arc>, } diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs index 505819fbf8a24..8d44084671aad 100644 --- a/src/libstd/sync/semaphore.rs +++ b/src/libstd/sync/semaphore.rs @@ -193,7 +193,7 @@ mod tests { tx.send(()).unwrap(); drop(s2.access()); tx.send(()).unwrap(); - }).detach(); + }); rx.recv().unwrap(); // wait for child to come alive } rx.recv().unwrap(); // wait for child to be done diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 088827dc0842d..278528bdb388b 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -132,7 +132,7 @@ fn spawn_in_pool(jobs: Arc>>) { } sentinel.cancel(); - }).detach(); + }); } #[cfg(test)] diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index bdf1bf3dfd02c..f940b6ed3682e 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -99,7 +99,7 @@ impl Helper { let _g = self.lock.lock().unwrap(); *self.shutdown.get() = true; self.cond.notify_one() - }).detach(); + }); rt::at_exit(move|:| { self.shutdown() }); *self.initialized.get() = true; diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 43abd96e46d1b..71321ed3b7174 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -16,7 +16,7 @@ //! each with their own stack and local state. //! //! Communication between threads can be done through -//! [channels](../../std/comm/index.html), Rust's message-passing +//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing //! types, along with [other forms of thread //! synchronization](../../std/sync/index.html) and shared-memory data //! structures. In particular, types that are guaranteed to be @@ -58,25 +58,45 @@ //! ```rust //! use std::thread::Thread; //! -//! let guard = Thread::spawn(move || { +//! let thread = Thread::spawn(move || { //! println!("Hello, World!"); //! // some computation here //! }); -//! let result = guard.join(); //! ``` //! -//! The `spawn` 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. +//! 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. +//! +//! ## Scoped threads //! -//! If you instead wish to *detach* the child thread, allowing it to outlive its -//! parent, you can use the `detach` method on the guard, +//! 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 `scoped` constructor: //! -//! A handle to the thread itself is available via the `thread` method on the -//! join guard. +//! ```rust +//! use std::thread::Thread; +//! +//! let guard = Thread::scoped(move || { +//! println!("Hello, World!"); +//! // some computation here +//! }); +//! // do some other work in the meantime +//! let result = 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. +//! +//! (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 +//! changes are needed before this is possible.) //! //! ## Configuring threads //! @@ -89,7 +109,7 @@ //! //! thread::Builder::new().name("child1".to_string()).spawn(move || { //! println!("Hello, world!") -//! }).detach(); +//! }); //! ``` //! //! ## Blocking support: park and unpark @@ -124,6 +144,8 @@ //! //! * It can be implemented highly efficiently on many platforms. +#![stable] + use any::Any; use boxed::Box; use cell::UnsafeCell; @@ -144,6 +166,7 @@ use sys_common::{stack, thread_info}; /// Thread configuation. Provides detailed control over the properties /// and behavior of new threads. +#[stable] pub struct Builder { // A name for the thread-to-be, for identification in panic messages name: Option, @@ -158,6 +181,7 @@ pub struct Builder { impl Builder { /// Generate the base configuration for spawning a thread, from which /// configuration methods can be chained. + #[stable] pub fn new() -> Builder { Builder { name: None, @@ -169,12 +193,14 @@ impl Builder { /// Name the thread-to-be. Currently the name is used for identification /// only in panic messages. + #[stable] pub fn name(mut self, name: String) -> Builder { self.name = Some(name); self } /// Set the size of the stack for the new thread. + #[stable] pub fn stack_size(mut self, size: uint) -> Builder { self.stack_size = Some(size); self @@ -194,19 +220,41 @@ impl Builder { self } - /// Spawn a new joinable thread, and return a JoinGuard guard for it. + /// Spawn a new detached thread, and return a handle to it. /// /// See `Thead::spawn` and the module doc for more details. - pub fn spawn(self, f: F) -> JoinGuard where - T: Send, F: FnOnce() -> T, F: Send - { - self.spawn_inner(Thunk::new(f)) + #[unstable = "may change with specifics of new Send semantics"] + pub fn spawn(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 } - fn spawn_inner(self, f: Thunk<(), T>) -> JoinGuard { + /// 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 = "may change with specifics of new Send semantics"] + pub fn scoped<'a, T, F>(self, f: F) -> 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, + } + } + + fn spawn_inner(self, f: Thunk<(), T>, finish: Thunk, ()>) + -> (imp::rust_thread, Thread) + { let Builder { name, stack_size, stdout, stderr } = self; let stack_size = stack_size.unwrap_or(rt::min_stack()); @@ -258,21 +306,14 @@ impl Builder { unwind::try(move || *ptr = Some(f.invoke(()))) } }; - unsafe { - *their_packet.0.get() = Some(match (output, try_result) { - (Some(data), Ok(_)) => Ok(data), - (None, Err(cause)) => Err(cause), - _ => unreachable!() - }); - } + finish.invoke(match (output, try_result) { + (Some(data), Ok(_)) => Ok(data), + (None, Err(cause)) => Err(cause), + _ => unreachable!() + }); }; - JoinGuard { - native: unsafe { imp::create(stack_size, Thunk::new(main)) }, - joined: false, - packet: my_packet, - thread: my_thread, - } + (unsafe { imp::create(stack_size, Thunk::new(main)) }, my_thread) } } @@ -285,13 +326,12 @@ struct Inner { unsafe impl Sync for Inner {} #[derive(Clone)] +#[stable] /// A handle to a thread. pub struct Thread { inner: Arc, } -unsafe impl Sync for Thread {} - impl Thread { // Used only internally to construct a thread object without spawning fn new(name: Option) -> Thread { @@ -304,30 +344,47 @@ impl Thread { } } - /// Spawn a new joinable thread, returning a `JoinGuard` for it. + /// 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. + #[unstable = "may change with specifics of new Send semantics"] + pub fn spawn(f: F) -> Thread where F: FnOnce(), F: Send + 'static { + Builder::new().spawn(f) + } + + /// 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`, or it will implicitly join the child - /// upon being dropped. To detach the child, allowing it to outlive the - /// current thread, use `detach`. See the module documentation for additional details. - pub fn spawn(f: F) -> JoinGuard where - T: Send, F: FnOnce() -> T, F: Send + /// 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. + #[unstable = "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().spawn(f) + Builder::new().scoped(f) } /// Gets a handle to the thread that invokes it. + #[stable] pub fn current() -> Thread { thread_info::current_thread() } /// Cooperatively give up a timeslice to the OS scheduler. + #[unstable = "name may change"] pub fn yield_now() { unsafe { imp::yield_now() } } /// Determines whether the current thread is panicking. #[inline] + #[stable] pub fn panicking() -> bool { unwind::panicking() } @@ -341,6 +398,7 @@ impl Thread { // 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. + #[unstable = "recently introduced"] pub fn park() { let thread = Thread::current(); let mut guard = thread.inner.lock.lock().unwrap(); @@ -353,6 +411,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// See the module doc for more detail. + #[unstable = "recently introduced"] pub fn unpark(&self) { let mut guard = self.inner.lock.lock().unwrap(); if !*guard { @@ -362,6 +421,7 @@ impl Thread { } /// Get the thread's name. + #[stable] pub fn name(&self) -> Option<&str> { self.inner.name.as_ref().map(|s| s.as_slice()) } @@ -375,6 +435,7 @@ impl thread_info::NewThread for Thread { /// Indicates the manner in which a thread exited. /// /// A thread that completes without panicking is considered to exit successfully. +#[stable] pub type Result = ::result::Result>; struct Packet(Arc>>>); @@ -382,21 +443,24 @@ struct Packet(Arc>>>); unsafe impl Send for Packet {} unsafe impl Sync for Packet {} -#[must_use] /// 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. -pub struct JoinGuard { +#[must_use] +#[unstable = "may change with specifics of new Send semantics"] +pub struct JoinGuard<'a, T: 'a> { native: imp::rust_thread, thread: Thread, joined: bool, packet: Packet, } -unsafe impl Sync for JoinGuard {} +#[stable] +unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {} -impl JoinGuard { +impl<'a, T: Send + 'a> JoinGuard<'a, T> { /// Extract a handle to the thread this guard will join on. + #[stable] pub fn thread(&self) -> &Thread { &self.thread } @@ -406,6 +470,7 @@ impl JoinGuard { /// /// If the child thread panics, `Err` is returned with the parameter given /// to `panic`. + #[stable] pub fn join(mut self) -> Result { assert!(!self.joined); unsafe { imp::join(self.native) }; @@ -414,8 +479,11 @@ impl JoinGuard { (*self.packet.0.get()).take().unwrap() } } +} +impl JoinGuard<'static, T> { /// Detaches the child thread, allowing it to outlive its parent. + #[experimental = "unsure whether this API imposes limitations elsewhere"] pub fn detach(mut self) { unsafe { imp::detach(self.native) }; self.joined = true; // avoid joining in the destructor @@ -424,7 +492,7 @@ impl JoinGuard { #[unsafe_destructor] #[stable] -impl Drop for JoinGuard { +impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> { fn drop(&mut self) { if !self.joined { unsafe { imp::join(self.native) }; @@ -449,14 +517,14 @@ mod test { #[test] fn test_unnamed_thread() { - Thread::spawn(move|| { + Thread::scoped(move|| { assert!(Thread::current().name().is_none()); }).join().map_err(|_| ()).unwrap(); } #[test] fn test_named_thread() { - Builder::new().name("ada lovelace".to_string()).spawn(move|| { + Builder::new().name("ada lovelace".to_string()).scoped(move|| { assert!(Thread::current().name().unwrap() == "ada lovelace".to_string()); }).join().map_err(|_| ()).unwrap(); } @@ -466,13 +534,13 @@ mod test { let (tx, rx) = channel(); Thread::spawn(move|| { tx.send(()).unwrap(); - }).detach(); + }); rx.recv().unwrap(); } #[test] fn test_join_success() { - match Thread::spawn(move|| -> String { + match Thread::scoped(move|| -> String { "Success!".to_string() }).join().as_ref().map(|s| s.as_slice()) { result::Result::Ok("Success!") => (), @@ -482,7 +550,7 @@ mod test { #[test] fn test_join_panic() { - match Thread::spawn(move|| { + match Thread::scoped(move|| { panic!() }).join() { result::Result::Err(_) => (), @@ -504,7 +572,7 @@ mod test { } else { f(i - 1, tx); } - }).detach(); + }); } f(10, tx); @@ -518,8 +586,8 @@ mod test { Thread::spawn(move|| { Thread::spawn(move|| { tx.send(()).unwrap(); - }).detach(); - }).detach(); + }); + }); rx.recv().unwrap(); } @@ -542,7 +610,7 @@ mod test { #[test] fn test_avoid_copying_the_body_spawn() { avoid_copying_the_body(|v| { - Thread::spawn(move || v.invoke(())).detach(); + Thread::spawn(move || v.invoke(())); }); } @@ -551,14 +619,14 @@ mod test { avoid_copying_the_body(|f| { Thread::spawn(move|| { f.invoke(()); - }).detach(); + }); }) } #[test] fn test_avoid_copying_the_body_join() { avoid_copying_the_body(|f| { - let _ = Thread::spawn(move|| { + let _ = Thread::scoped(move|| { f.invoke(()) }).join(); }) @@ -574,21 +642,21 @@ mod test { fn child_no(x: uint) -> Thunk { return Thunk::new(move|| { if x < GENERATIONS { - Thread::spawn(move|| child_no(x+1).invoke(())).detach(); + Thread::spawn(move|| child_no(x+1).invoke(())); } }); } - Thread::spawn(|| child_no(0).invoke(())).detach(); + Thread::spawn(|| child_no(0).invoke(())); } #[test] fn test_simple_newsched_spawn() { - Thread::spawn(move || {}).detach(); + Thread::spawn(move || {}); } #[test] fn test_try_panic_message_static_str() { - match Thread::spawn(move|| { + match Thread::scoped(move|| { panic!("static string"); }).join() { Err(e) => { @@ -602,7 +670,7 @@ mod test { #[test] fn test_try_panic_message_owned_str() { - match Thread::spawn(move|| { + match Thread::scoped(move|| { panic!("owned string".to_string()); }).join() { Err(e) => { @@ -616,7 +684,7 @@ mod test { #[test] fn test_try_panic_message_any() { - match Thread::spawn(move|| { + match Thread::scoped(move|| { panic!(box 413u16 as Box); }).join() { Err(e) => { @@ -634,7 +702,7 @@ mod test { fn test_try_panic_message_unit_struct() { struct Juju; - match Thread::spawn(move|| { + match Thread::scoped(move|| { panic!(Juju) }).join() { Err(ref e) if e.is::() => {} @@ -648,7 +716,7 @@ mod test { let mut reader = ChanReader::new(rx); let stdout = ChanWriter::new(tx); - let r = Builder::new().stdout(box stdout as Box).spawn(move|| { + let r = Builder::new().stdout(box stdout as Box).scoped(move|| { print!("Hello, world!"); }).join(); assert!(r.is_ok()); diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 4d47703d30f7d..e7c4e4ccdfb88 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -86,7 +86,7 @@ pub mod __impl { /// assert_eq!(*f.borrow(), 1); /// *f.borrow_mut() = 3; /// }); -/// }).detach(); +/// }); /// /// // we retain our original value of 2 despite the child thread /// FOO.with(|f| { @@ -580,7 +580,7 @@ mod tests { } thread_local!(static FOO: Foo = foo()); - Thread::spawn(|| { + Thread::scoped(|| { assert!(FOO.state() == State::Uninitialized); FOO.with(|_| { assert!(FOO.state() == State::Valid); @@ -644,7 +644,7 @@ mod tests { } } - Thread::spawn(move|| { + Thread::scoped(move|| { drop(S1); }).join().ok().unwrap(); } @@ -662,7 +662,7 @@ mod tests { } } - Thread::spawn(move|| unsafe { + Thread::scoped(move|| unsafe { K1.with(|s| *s.get() = Some(S1)); }).join().ok().unwrap(); } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index a791221663031..5f10573f95e9f 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1137,11 +1137,11 @@ pub fn run_test(opts: &TestOpts, cfg = cfg.stderr(box stderr as Box); } - let result_guard = cfg.spawn(move || { testfn.invoke(()) }); + let result_guard = cfg.scoped(move || { testfn.invoke(()) }); let stdout = reader.read_to_end().unwrap().into_iter().collect(); let test_result = calc_result(&desc, result_guard.join()); monitor_ch.send((desc.clone(), test_result, stdout)).unwrap(); - }).detach(); + }); } match testfn { diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index ec4c0281d5597..673c38697b79c 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -15,6 +15,6 @@ pub fn foo(x: T) -> Receiver { let (tx, rx) = channel(); Thread::spawn(move|| { tx.send(x.clone()); - }).detach(); + }); rx } diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index d1126e7425273..387601de8284c 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -64,7 +64,7 @@ fn run(args: &[String]) { let mut worker_results = Vec::new(); for _ in range(0u, workers) { let to_child = to_child.clone(); - worker_results.push(Thread::spawn(move|| { + worker_results.push(Thread::scoped(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)).unwrap(); @@ -74,7 +74,7 @@ fn run(args: &[String]) { } Thread::spawn(move|| { server(&from_parent, &to_parent); - }).detach(); + }); for r in worker_results.into_iter() { let _ = r.join(); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index ef22aac776e03..d6d01e5452b95 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -59,7 +59,7 @@ fn run(args: &[String]) { let mut worker_results = Vec::new(); let from_parent = if workers == 1 { let (to_child, from_parent) = channel(); - worker_results.push(Thread::spawn(move|| { + worker_results.push(Thread::scoped(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); @@ -71,7 +71,7 @@ fn run(args: &[String]) { let (to_child, from_parent) = channel(); for _ in range(0u, workers) { let to_child = to_child.clone(); - worker_results.push(Thread::spawn(move|| { + worker_results.push(Thread::scoped(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); @@ -83,7 +83,7 @@ fn run(args: &[String]) { }; Thread::spawn(move|| { server(&from_parent, &to_parent); - }).detach(); + }); for r in worker_results.into_iter() { let _ = r.join(); diff --git a/src/test/bench/rt-messaging-ping-pong.rs b/src/test/bench/rt-messaging-ping-pong.rs index 5ecc580de08d5..b854dc11b988a 100644 --- a/src/test/bench/rt-messaging-ping-pong.rs +++ b/src/test/bench/rt-messaging-ping-pong.rs @@ -35,7 +35,7 @@ fn ping_pong_bench(n: uint, m: uint) { // Create a channel: B->A let (btx, brx) = channel(); - let guard_a = Thread::spawn(move|| { + let guard_a = Thread::scoped(move|| { let (tx, rx) = (atx, brx); for _ in range(0, n) { tx.send(()).unwrap(); @@ -43,7 +43,7 @@ fn ping_pong_bench(n: uint, m: uint) { } }); - let guard_b = Thread::spawn(move|| { + let guard_b = Thread::scoped(move|| { let (tx, rx) = (btx, arx); for _ in range(0, n) { rx.recv().unwrap(); diff --git a/src/test/bench/rt-parfib.rs b/src/test/bench/rt-parfib.rs index 8b212555d4011..37210cd93f1b3 100644 --- a/src/test/bench/rt-parfib.rs +++ b/src/test/bench/rt-parfib.rs @@ -25,7 +25,7 @@ fn parfib(n: uint) -> uint { let (tx, rx) = channel(); Thread::spawn(move|| { tx.send(parfib(n-1)); - }).detach(); + }); let m2 = parfib(n-2); return (rx.recv().unwrap() + m2); } diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index c7a43d61a9a86..737776368dd0c 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -95,7 +95,7 @@ fn main() { let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| { use std::num::Int; let iterations = 2i.pow((max_depth - depth + min_depth) as uint); - Thread::spawn(move|| { + Thread::scoped(move|| { let mut chk = 0; for i in range(1, iterations + 1) { let arena = TypedArena::new(); diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 96bca25d1c455..5c36fccc7f5d8 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -195,7 +195,7 @@ fn rendezvous(nn: uint, set: Vec) { from_rendezvous, to_rendezvous, to_rendezvous_log); - }).detach(); + }); to_creature }).collect(); diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index 8ce365f765d85..261741c073f3a 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -168,7 +168,7 @@ fn fannkuch(n: i32) -> (i32, i32) { for (i, j) in range(0, N).zip(iter::count(0, k)) { let max = cmp::min(j+k, perm.max()); - futures.push(Thread::spawn(move|| { + futures.push(Thread::scoped(move|| { work(perm, j as uint, max as uint) })) } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 39c839ba11403..3845c6c593c5f 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -173,7 +173,7 @@ fn main() { Thread::spawn(move|| { make_sequence_processor(sz, &from_parent, &to_parent_); - }).detach(); + }); to_child }).collect:: >> >(); diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 4f71ea8cbe997..d0ff47628d432 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -304,11 +304,11 @@ fn main() { let nb_freqs: Vec<_> = range(1u, 3).map(|i| { let input = input.clone(); - (i, Thread::spawn(move|| generate_frequencies(input.as_slice(), i))) + (i, Thread::scoped(move|| generate_frequencies(input.as_slice(), i))) }).collect(); let occ_freqs: Vec<_> = OCCURRENCES.iter().map(|&occ| { let input = input.clone(); - Thread::spawn(move|| generate_frequencies(input.as_slice(), occ.len())) + Thread::scoped(move|| generate_frequencies(input.as_slice(), occ.len())) }).collect(); for (i, freq) in nb_freqs.into_iter() { diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 16d6036d4c40f..f6124c1271f05 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -82,7 +82,7 @@ fn mandelbrot(w: uint, mut out: W) -> io::IoResult<()> { let mut precalc_i = Vec::with_capacity(h); let precalc_futures = range(0, WORKERS).map(|i| { - Thread::spawn(move|| { + Thread::scoped(move|| { let mut rs = Vec::with_capacity(w / WORKERS); let mut is = Vec::with_capacity(w / WORKERS); @@ -123,7 +123,7 @@ fn mandelbrot(w: uint, mut out: W) -> io::IoResult<()> { let vec_init_r = arc_init_r.clone(); let vec_init_i = arc_init_i.clone(); - Thread::spawn(move|| { + Thread::scoped(move|| { let mut res: Vec = Vec::with_capacity((chunk_size * w) / 8); let init_r_slice = vec_init_r.as_slice(); diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index ca3d10afa5d47..34a036eff3750 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -321,7 +321,7 @@ fn par_search(masks: Vec>>) -> Data { let mut data = Data::new(); search(&*masks, m, 1, List::Cons(m, &List::Nil), &mut data); tx.send(data).unwrap(); - }).detach(); + }); } // collecting the results diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 84ceb432048bc..3953d3f9cdd33 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -35,15 +35,15 @@ fn fib(n: int) -> int { } else { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - Thread::spawn(move|| pfib(&tx2, n - 1)).detach(); + Thread::spawn(move|| pfib(&tx2, n - 1)); let tx2 = tx1.clone(); - Thread::spawn(move|| pfib(&tx2, n - 2)).detach(); + Thread::spawn(move|| pfib(&tx2, n - 2)); tx.send(rx.recv().unwrap() + rx.recv().unwrap()); } } let (tx, rx) = channel(); - Thread::spawn(move|| pfib(&tx, n) ).detach(); + Thread::spawn(move|| pfib(&tx, n) ); rx.recv().unwrap() } @@ -78,7 +78,7 @@ fn stress_task(id: int) { fn stress(num_tasks: int) { let mut results = Vec::new(); for i in range(0, num_tasks) { - results.push(Thread::spawn(move|| { + results.push(Thread::scoped(move|| { stress_task(i); })); } diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 9dd1003785051..da427b36e8d0f 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -46,10 +46,10 @@ fn start(n_tasks: int, token: int) { tx.send(token); for i in range(2, n_tasks + 1) { let (tx, next_rx) = channel(); - Thread::spawn(move|| roundtrip(i, tx, rx)).detach(); + Thread::spawn(move|| roundtrip(i, tx, rx)); rx = next_rx; } - Thread::spawn(move|| roundtrip(1, tx, rx)).detach(); + Thread::spawn(move|| roundtrip(1, tx, rx)); } fn roundtrip(id: int, tx: Sender, rx: Receiver) { diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 9e78ede74ca91..55e8dcbb6e8fb 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -36,7 +36,7 @@ fn main() { fn run(repeat: int, depth: int) { for _ in range(0, repeat) { let dur = Duration::span(|| { - let _ = Thread::spawn(move|| { + let _ = Thread::scoped(move|| { recurse_or_panic(depth, None) }).join(); }); diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs index 30918d4909035..a2a380279f34d 100644 --- a/src/test/bench/task-perf-jargon-metal-smoke.rs +++ b/src/test/bench/task-perf-jargon-metal-smoke.rs @@ -35,7 +35,7 @@ fn child_generation(gens_left: uint, tx: Sender<()>) { } else { tx.send(()).unwrap() } - }).detach(); + }); } fn main() { diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 488a5ec9edada..eb1e30e284676 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -15,7 +15,7 @@ use std::thread::Thread; fn f(n: uint) { let mut i = 0u; while i < n { - let _ = Thread::spawn(move|| g()).join(); + let _ = Thread::scoped(move|| g()).join(); i += 1u; } } @@ -33,5 +33,5 @@ fn main() { }; let n = args[1].parse().unwrap(); let mut i = 0u; - while i < n { Thread::spawn(move|| f(n) ).detach(); i += 1u; } + while i < n { Thread::spawn(move|| f(n) ); i += 1u; } } diff --git a/src/test/run-fail/panic-task-name-none.rs b/src/test/run-fail/panic-task-name-none.rs index c943dfe9f0c60..9beee3b1843f3 100644 --- a/src/test/run-fail/panic-task-name-none.rs +++ b/src/test/run-fail/panic-task-name-none.rs @@ -13,7 +13,7 @@ use std::thread::Thread; fn main() { - let r: Result = Thread::spawn(move|| { + let r: Result = Thread::scoped(move|| { panic!("test"); 1i }).join(); diff --git a/src/test/run-fail/panic-task-name-owned.rs b/src/test/run-fail/panic-task-name-owned.rs index 57901ebcfc622..714cec6fb3d20 100644 --- a/src/test/run-fail/panic-task-name-owned.rs +++ b/src/test/run-fail/panic-task-name-owned.rs @@ -13,7 +13,7 @@ use std::thread::Builder; fn main() { - let r: Result = Builder::new().name("owned name".to_string()).spawn(move|| { + let r: Result = Builder::new().name("owned name".to_string()).scoped(move|| { panic!("test"); 1i }).join(); diff --git a/src/test/run-fail/task-spawn-barefn.rs b/src/test/run-fail/task-spawn-barefn.rs index 8aade64163056..d58148810da1f 100644 --- a/src/test/run-fail/task-spawn-barefn.rs +++ b/src/test/run-fail/task-spawn-barefn.rs @@ -15,7 +15,7 @@ use std::thread::Thread; fn main() { // the purpose of this test is to make sure that task::spawn() // works when provided with a bare function: - let r = Thread::spawn(startfn).join(); + let r = Thread::scoped(startfn).join(); if r.is_err() { panic!() } diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make/static-unwinding/main.rs index faac858e76e0b..bd88cb19aa7c0 100644 --- a/src/test/run-make/static-unwinding/main.rs +++ b/src/test/run-make/static-unwinding/main.rs @@ -22,7 +22,7 @@ impl Drop for A { } fn main() { - Thread::spawn(move|| { + Thread::scoped(move|| { let _a = A; lib::callback(|| panic!()); 1i diff --git a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs index 440b7afa984f7..526819940d003 100644 --- a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs +++ b/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs @@ -45,5 +45,5 @@ pub fn fails() { } pub fn main() { - Thread::spawn(fails).join(); + Thread::scoped(fails).join(); } diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index 3298976de6ce3..eeb044e560422 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -90,7 +90,7 @@ pub fn test_destroy_actually_kills(force: bool) { _ = rx2.recv() => unsafe { libc::exit(1) }, _ = rx1.recv() => {} } - }).detach(); + }); match p.wait().unwrap() { ExitStatus(..) => panic!("expected a signal"), ExitSignal(..) => tx.send(()).unwrap(), diff --git a/src/test/run-pass/foreign-call-no-runtime.rs b/src/test/run-pass/foreign-call-no-runtime.rs index ce3e447350d40..c1df9d53ad440 100644 --- a/src/test/run-pass/foreign-call-no-runtime.rs +++ b/src/test/run-pass/foreign-call-no-runtime.rs @@ -21,7 +21,7 @@ extern { pub fn main() { unsafe { - Thread::spawn(move|| { + Thread::scoped(move|| { let i = &100i; rust_dbg_call(callback, mem::transmute(i)); }).join(); diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 3bcce5388715d..f83698edc9052 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -1,4 +1,3 @@ - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -37,7 +36,7 @@ mod map_reduce { for i in inputs.iter() { let ctrl = ctrl.clone(); let i = i.clone(); - Thread::spawn(move|| map_task(ctrl.clone(), i.clone()) ).detach(); + Thread::spawn(move|| map_task(ctrl.clone(), i.clone()) ); } } diff --git a/src/test/run-pass/issue-12684.rs b/src/test/run-pass/issue-12684.rs index 856fbbd00b20b..a6a4d21e8f2c0 100644 --- a/src/test/run-pass/issue-12684.rs +++ b/src/test/run-pass/issue-12684.rs @@ -12,7 +12,7 @@ use std::time::Duration; use std::thread::Thread; fn main() { - Thread::spawn(move|| customtask()).join().ok().unwrap(); + Thread::scoped(move|| customtask()).join().ok().unwrap(); } fn customtask() { diff --git a/src/test/run-pass/issue-13494.rs b/src/test/run-pass/issue-13494.rs index b9339c1cc0d03..bef0ff5fc2cd2 100644 --- a/src/test/run-pass/issue-13494.rs +++ b/src/test/run-pass/issue-13494.rs @@ -22,7 +22,7 @@ fn helper(rx: Receiver>) { fn main() { let (tx, rx) = channel(); - let _t = Thread::spawn(move|| { helper(rx) }).detach(); + let _t = Thread::spawn(move|| { helper(rx) }); let (snd, rcv) = channel::(); for _ in range(1i, 100000i) { snd.send(1i).unwrap(); diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs index b2b819a110305..6b03a499f1577 100644 --- a/src/test/run-pass/issue-16560.rs +++ b/src/test/run-pass/issue-16560.rs @@ -20,7 +20,7 @@ fn main() { // Check that both closures are capturing by value assert_eq!(1, mem::size_of_val(&closure)); - Thread::spawn(move|| { + Thread::scoped(move|| { let ok = closure; }).join().ok().unwrap(); } diff --git a/src/test/run-pass/issue-16671.rs b/src/test/run-pass/issue-16671.rs index 99758f9f777d6..e25b3e8e89c6c 100644 --- a/src/test/run-pass/issue-16671.rs +++ b/src/test/run-pass/issue-16671.rs @@ -24,5 +24,5 @@ pub fn main() { let mut stdin = std::io::stdin(); Thread::spawn(move|| { let _ = stdin.read_to_end(); - }).detach(); + }); } diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index 4bbbe978192b1..810bf385d7e0b 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -14,7 +14,7 @@ use std::thunk::Thunk; static generations: uint = 1024+256+128+49; fn spawn(f: Thunk) { - Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(())).detach() + Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(())); } fn child_no(x: uint) -> Thunk { diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs index 30e1a14ecff8f..9c00348ad6a51 100644 --- a/src/test/run-pass/issue-4446.rs +++ b/src/test/run-pass/issue-4446.rs @@ -17,7 +17,7 @@ pub fn main() { tx.send("hello, world").unwrap(); - Thread::spawn(move|| { + Thread::scoped(move|| { println(rx.recv().unwrap()); }).join().ok().unwrap(); } diff --git a/src/test/run-pass/issue-4448.rs b/src/test/run-pass/issue-4448.rs index 7e53722726f2c..a19bfca721a7c 100644 --- a/src/test/run-pass/issue-4448.rs +++ b/src/test/run-pass/issue-4448.rs @@ -14,7 +14,7 @@ use std::thread::Thread; pub fn main() { let (tx, rx) = channel::<&'static str>(); - let t = Thread::spawn(move|| { + let t = Thread::scoped(move|| { assert_eq!(rx.recv().unwrap(), "hello, world"); }); diff --git a/src/test/run-pass/issue-8460.rs b/src/test/run-pass/issue-8460.rs index 3d5e32972e724..3ea6d5d4f2fcb 100644 --- a/src/test/run-pass/issue-8460.rs +++ b/src/test/run-pass/issue-8460.rs @@ -12,24 +12,24 @@ use std::{int, i8, i16, i32, i64}; use std::thread::Thread; fn main() { - assert!(Thread::spawn(move|| int::MIN / -1).join().is_err()); - assert!(Thread::spawn(move|| i8::MIN / -1).join().is_err()); - assert!(Thread::spawn(move|| i16::MIN / -1).join().is_err()); - assert!(Thread::spawn(move|| i32::MIN / -1).join().is_err()); - assert!(Thread::spawn(move|| i64::MIN / -1).join().is_err()); - assert!(Thread::spawn(move|| 1i / 0).join().is_err()); - assert!(Thread::spawn(move|| 1i8 / 0).join().is_err()); - assert!(Thread::spawn(move|| 1i16 / 0).join().is_err()); - assert!(Thread::spawn(move|| 1i32 / 0).join().is_err()); - assert!(Thread::spawn(move|| 1i64 / 0).join().is_err()); - assert!(Thread::spawn(move|| int::MIN % -1).join().is_err()); - assert!(Thread::spawn(move|| i8::MIN % -1).join().is_err()); - assert!(Thread::spawn(move|| i16::MIN % -1).join().is_err()); - assert!(Thread::spawn(move|| i32::MIN % -1).join().is_err()); - assert!(Thread::spawn(move|| i64::MIN % -1).join().is_err()); - assert!(Thread::spawn(move|| 1i % 0).join().is_err()); - assert!(Thread::spawn(move|| 1i8 % 0).join().is_err()); - assert!(Thread::spawn(move|| 1i16 % 0).join().is_err()); - assert!(Thread::spawn(move|| 1i32 % 0).join().is_err()); - assert!(Thread::spawn(move|| 1i64 % 0).join().is_err()); + assert!(Thread::scoped(move|| int::MIN / -1).join().is_err()); + assert!(Thread::scoped(move|| i8::MIN / -1).join().is_err()); + assert!(Thread::scoped(move|| i16::MIN / -1).join().is_err()); + assert!(Thread::scoped(move|| i32::MIN / -1).join().is_err()); + assert!(Thread::scoped(move|| i64::MIN / -1).join().is_err()); + assert!(Thread::scoped(move|| 1i / 0).join().is_err()); + assert!(Thread::scoped(move|| 1i8 / 0).join().is_err()); + assert!(Thread::scoped(move|| 1i16 / 0).join().is_err()); + assert!(Thread::scoped(move|| 1i32 / 0).join().is_err()); + assert!(Thread::scoped(move|| 1i64 / 0).join().is_err()); + assert!(Thread::scoped(move|| int::MIN % -1).join().is_err()); + assert!(Thread::scoped(move|| i8::MIN % -1).join().is_err()); + assert!(Thread::scoped(move|| i16::MIN % -1).join().is_err()); + assert!(Thread::scoped(move|| i32::MIN % -1).join().is_err()); + assert!(Thread::scoped(move|| i64::MIN % -1).join().is_err()); + assert!(Thread::scoped(move|| 1i % 0).join().is_err()); + assert!(Thread::scoped(move|| 1i8 % 0).join().is_err()); + assert!(Thread::scoped(move|| 1i16 % 0).join().is_err()); + assert!(Thread::scoped(move|| 1i32 % 0).join().is_err()); + assert!(Thread::scoped(move|| 1i64 % 0).join().is_err()); } diff --git a/src/test/run-pass/issue-8827.rs b/src/test/run-pass/issue-8827.rs index 39695a8339f08..d8b7490124f70 100644 --- a/src/test/run-pass/issue-8827.rs +++ b/src/test/run-pass/issue-8827.rs @@ -26,7 +26,7 @@ fn periodical(n: int) -> Receiver { Err(..) => break } } - }).detach(); + }); return port; } @@ -41,7 +41,7 @@ fn integers() -> Receiver { } i = i + 1; } - }).detach(); + }); return port; } @@ -58,4 +58,3 @@ fn main() { } } } - diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index 787d0e98e2bfc..a72cfad2cb88e 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -27,7 +27,7 @@ impl fmt::Show for Foo { } pub fn main() { - Thread::spawn(move|| { + Thread::scoped(move|| { let mut f = Foo(Cell::new(0)); println!("{:?}", f); let Foo(ref mut f) = f; diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs index 93bb9557604c4..cb52ba74bbd68 100644 --- a/src/test/run-pass/macro-with-braces-in-expr-position.rs +++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs @@ -14,7 +14,7 @@ macro_rules! expr { ($e: expr) => { $e } } macro_rules! spawn { ($($code: tt)*) => { - expr!(Thread::spawn(move|| {$($code)*}).detach()) + expr!(Thread::spawn(move|| {$($code)*})) } } diff --git a/src/test/run-pass/no-landing-pads.rs b/src/test/run-pass/no-landing-pads.rs index 6b1553cd9f600..64e78c3483bba 100644 --- a/src/test/run-pass/no-landing-pads.rs +++ b/src/test/run-pass/no-landing-pads.rs @@ -23,7 +23,7 @@ impl Drop for A { } fn main() { - Thread::spawn(move|| -> () { + Thread::scoped(move|| -> () { let _a = A; panic!(); }).join().unwrap_err(); diff --git a/src/test/run-pass/panic-in-dtor-drops-fields.rs b/src/test/run-pass/panic-in-dtor-drops-fields.rs index 5c692bf880181..3cc01b967ce6a 100644 --- a/src/test/run-pass/panic-in-dtor-drops-fields.rs +++ b/src/test/run-pass/panic-in-dtor-drops-fields.rs @@ -33,10 +33,9 @@ impl Drop for B { } pub fn main() { - let ret = Thread::spawn(move|| { + let ret = Thread::scoped(move|| { let _a = A { b: B { foo: 3 } }; }).join(); assert!(ret.is_err()); unsafe { assert!(dropped); } } - diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs index 3ed835dc5bdf9..a6e4716c3b8a3 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -22,7 +22,7 @@ fn test05() { println!("{}", *three + n); // will copy x into the closure assert_eq!(*three, 3); }; - Thread::spawn(move|| { + Thread::scoped(move|| { test05_start(fn_to_send); }).join().ok().unwrap(); } diff --git a/src/test/run-pass/sepcomp-unwind.rs b/src/test/run-pass/sepcomp-unwind.rs index 246957a4f4608..b8bb3b4e7f8c3 100644 --- a/src/test/run-pass/sepcomp-unwind.rs +++ b/src/test/run-pass/sepcomp-unwind.rs @@ -36,5 +36,5 @@ mod b { } fn main() { - Thread::spawn(move|| { ::b::g() }).join().unwrap_err(); + Thread::scoped(move|| { ::b::g() }).join().unwrap_err(); } diff --git a/src/test/run-pass/slice-panic-1.rs b/src/test/run-pass/slice-panic-1.rs index ebe6e974c26cf..8b9a3f10a60bc 100644 --- a/src/test/run-pass/slice-panic-1.rs +++ b/src/test/run-pass/slice-panic-1.rs @@ -28,6 +28,6 @@ fn foo() { } fn main() { - let _ = Thread::spawn(move|| foo()).join(); + let _ = Thread::scoped(move|| foo()).join(); unsafe { assert!(DTOR_COUNT == 2); } } diff --git a/src/test/run-pass/slice-panic-2.rs b/src/test/run-pass/slice-panic-2.rs index 6bbd1ac7b2d9f..94a0530bffb94 100644 --- a/src/test/run-pass/slice-panic-2.rs +++ b/src/test/run-pass/slice-panic-2.rs @@ -32,6 +32,6 @@ fn foo() { } fn main() { - let _ = Thread::spawn(move|| foo()).join(); + let _ = Thread::scoped(move|| foo()).join(); unsafe { assert!(DTOR_COUNT == 2); } } diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index bb9de7cecc98c..eaad2abe8f72e 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -25,6 +25,6 @@ fn iotask(_tx: &ctx, ip: String) { pub fn main() { let (tx, _rx) = channel::(); - let t = Thread::spawn(move|| iotask(&tx, "localhost".to_string()) ); + let t = Thread::scoped(move|| iotask(&tx, "localhost".to_string()) ); t.join().ok().unwrap(); } diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs index 820dd49142ac6..8f937afa6b932 100644 --- a/src/test/run-pass/spawn.rs +++ b/src/test/run-pass/spawn.rs @@ -11,7 +11,7 @@ use std::thread::Thread; pub fn main() { - Thread::spawn(move|| child(10)).join().ok().unwrap(); + Thread::scoped(move|| child(10)).join().ok().unwrap(); } fn child(i: int) { println!("{}", i); assert!((i == 10)); } diff --git a/src/test/run-pass/spawn2.rs b/src/test/run-pass/spawn2.rs index 50c2d79132ef5..75104a4ddef00 100644 --- a/src/test/run-pass/spawn2.rs +++ b/src/test/run-pass/spawn2.rs @@ -11,7 +11,7 @@ use std::thread::Thread; pub fn main() { - let t = Thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); + let t = Thread::scoped(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); t.join().ok().unwrap(); } diff --git a/src/test/run-pass/spawning-with-debug.rs b/src/test/run-pass/spawning-with-debug.rs index ea594977f905c..858b7a83c6274 100644 --- a/src/test/run-pass/spawning-with-debug.rs +++ b/src/test/run-pass/spawning-with-debug.rs @@ -17,5 +17,5 @@ use std::thread::Builder; pub fn main() { let mut t = Builder::new(); - t.spawn(move|| ()).detach(); + t.spawn(move|| ()); } diff --git a/src/test/run-pass/task-comm-1.rs b/src/test/run-pass/task-comm-1.rs index 966bb6aa7358b..180f6e09ba99b 100644 --- a/src/test/run-pass/task-comm-1.rs +++ b/src/test/run-pass/task-comm-1.rs @@ -15,6 +15,6 @@ pub fn main() { test00(); } fn start() { println!("Started / Finished task."); } fn test00() { - let _ = Thread::spawn(move|| start() ).join(); + let _ = Thread::scoped(move|| start() ).join(); println!("Completing."); } diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index 561c9e91553dd..da080408ad17c 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -16,7 +16,7 @@ fn start(_task_number: int) { println!("Started / Finished task."); } fn test00() { let i: int = 0; - let mut result = Thread::spawn(move|| { + let mut result = Thread::scoped(move|| { start(i) }); diff --git a/src/test/run-pass/task-comm-13.rs b/src/test/run-pass/task-comm-13.rs index 50667d375a13c..429c6ce9fb371 100644 --- a/src/test/run-pass/task-comm-13.rs +++ b/src/test/run-pass/task-comm-13.rs @@ -19,6 +19,6 @@ fn start(tx: &Sender, start: int, number_of_messages: int) { pub fn main() { println!("Check that we don't deadlock."); let (tx, rx) = channel(); - let _ = Thread::spawn(move|| { start(&tx, 0, 10) }).join(); + let _ = Thread::scoped(move|| { start(&tx, 0, 10) }).join(); println!("Joined task"); } diff --git a/src/test/run-pass/task-comm-14.rs b/src/test/run-pass/task-comm-14.rs index 82e4bd8f6d2a1..0735e3996eec1 100644 --- a/src/test/run-pass/task-comm-14.rs +++ b/src/test/run-pass/task-comm-14.rs @@ -19,7 +19,7 @@ pub fn main() { while (i > 0) { println!("{}", i); let tx = tx.clone(); - Thread::spawn({let i = i; move|| { child(i, &tx) }}).detach(); + Thread::spawn({let i = i; move|| { child(i, &tx) }}); i = i - 1; } diff --git a/src/test/run-pass/task-comm-17.rs b/src/test/run-pass/task-comm-17.rs index e9f7cdf96a83a..9db5465f7e96e 100644 --- a/src/test/run-pass/task-comm-17.rs +++ b/src/test/run-pass/task-comm-17.rs @@ -18,5 +18,5 @@ fn f() { } pub fn main() { - let _t = Thread::spawn(move|| f() ).join(); + let _t = Thread::scoped(move|| f() ).join(); } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index a002a597481e4..306cc0ffcef7c 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -40,7 +40,7 @@ fn test00() { let mut results = Vec::new(); while i < number_of_tasks { let tx = tx.clone(); - results.push(Thread::spawn({ + results.push(Thread::scoped({ let i = i; move|| { test00_start(&tx, i, number_of_messages) diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index d9faf6ee4e4b2..6d8de4a6a53d6 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -24,7 +24,7 @@ fn test00() { let (tx, rx) = channel(); let number_of_messages: int = 10; - let result = Thread::spawn(move|| { + let result = Thread::scoped(move|| { test00_start(&tx, number_of_messages); }); diff --git a/src/test/run-pass/task-stderr.rs b/src/test/run-pass/task-stderr.rs index a7eabe0edb384..7ff5960375cb2 100644 --- a/src/test/run-pass/task-stderr.rs +++ b/src/test/run-pass/task-stderr.rs @@ -17,7 +17,7 @@ fn main() { let mut reader = ChanReader::new(rx); let stderr = ChanWriter::new(tx); - let res = thread::Builder::new().stderr(box stderr as Box).spawn(move|| -> () { + let res = thread::Builder::new().stderr(box stderr as Box).scoped(move|| -> () { panic!("Hello, world!") }).join(); assert!(res.is_err()); diff --git a/src/test/run-pass/tcp-accept-stress.rs b/src/test/run-pass/tcp-accept-stress.rs index 3e6158ca82193..cd3cb872fd3bc 100644 --- a/src/test/run-pass/tcp-accept-stress.rs +++ b/src/test/run-pass/tcp-accept-stress.rs @@ -52,7 +52,7 @@ fn test() { } } srv_tx.send(()); - }).detach(); + }); } for _ in range(0, N) { @@ -62,7 +62,7 @@ fn test() { let _s = TcpStream::connect(addr).unwrap(); } cli_tx.send(()); - }).detach(); + }); } drop((cli_tx, srv_tx)); diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 7d226aa942032..0109d64ad5347 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -29,7 +29,7 @@ fn main() { timer::sleep(Duration::milliseconds(30 * 1000)); println!("timed out!"); unsafe { libc::exit(1) } - }).detach(); + }); let (tx, rx) = channel(); Thread::spawn(move || -> () { @@ -47,7 +47,7 @@ fn main() { stream.read_byte(); stream.write(&[2]); } - }).detach(); + }); let addr = rx.recv().unwrap(); let (tx, rx) = channel(); @@ -64,7 +64,7 @@ fn main() { Err(e) => debug!("{}", e) } tx.send(()).unwrap(); - }).detach(); + }); } // Wait for all clients to exit, but don't wait for the server to exit. The diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index bf108ecd6764a..b931bd9609c6f 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -42,7 +42,7 @@ fn test_rm_tempdir() { tx.send(tmp.path().clone()).unwrap(); panic!("panic to unwind past `tmp`"); }; - let _ = Thread::spawn(f).join(); + let _ = Thread::scoped(f).join(); let path = rx.recv().unwrap(); assert!(!path.exists()); @@ -52,7 +52,7 @@ fn test_rm_tempdir() { let _tmp = tmp; panic!("panic to unwind past `tmp`"); }; - let _ = Thread::spawn(f).join(); + let _ = Thread::scoped(f).join(); assert!(!path.exists()); let path; @@ -60,7 +60,7 @@ fn test_rm_tempdir() { let f = move|:| { TempDir::new("test_rm_tempdir").unwrap() }; - let tmp = Thread::spawn(f).join().ok().expect("test_rm_tmdir"); + let tmp = Thread::scoped(f).join().ok().expect("test_rm_tmdir"); path = tmp.path().clone(); assert!(path.exists()); } @@ -84,7 +84,7 @@ fn test_rm_tempdir_close() { tmp.close(); panic!("panic when unwinding past `tmp`"); }; - let _ = Thread::spawn(f).join(); + let _ = Thread::scoped(f).join(); let path = rx.recv().unwrap(); assert!(!path.exists()); @@ -95,7 +95,7 @@ fn test_rm_tempdir_close() { tmp.close(); panic!("panic when unwinding past `tmp`"); }; - let _ = Thread::spawn(f).join(); + let _ = Thread::scoped(f).join(); assert!(!path.exists()); let path; @@ -103,7 +103,7 @@ fn test_rm_tempdir_close() { let f = move|:| { TempDir::new("test_rm_tempdir").unwrap() }; - let tmp = Thread::spawn(f).join().ok().expect("test_rm_tmdir"); + let tmp = Thread::scoped(f).join().ok().expect("test_rm_tmdir"); path = tmp.path().clone(); assert!(path.exists()); tmp.close(); @@ -177,7 +177,7 @@ pub fn test_rmdir_recursive_ok() { } pub fn dont_double_panic() { - let r: Result<(), _> = Thread::spawn(move|| { + let r: Result<(), _> = Thread::scoped(move|| { let tmpdir = TempDir::new("test").unwrap(); // Remove the temporary directory so that TempDir sees // an error on drop diff --git a/src/test/run-pass/terminate-in-initializer.rs b/src/test/run-pass/terminate-in-initializer.rs index 4270ecc745092..bfd1f5f4a74dd 100644 --- a/src/test/run-pass/terminate-in-initializer.rs +++ b/src/test/run-pass/terminate-in-initializer.rs @@ -22,13 +22,13 @@ fn test_ret() { let _x: Box = return; } fn test_panic() { fn f() { let _x: Box = panic!(); } - Thread::spawn(move|| f() ).join().err().unwrap(); + Thread::scoped(move|| f() ).join().err().unwrap(); } fn test_panic_indirect() { fn f() -> ! { panic!(); } fn g() { let _x: Box = f(); } - Thread::spawn(move|| g() ).join().err().unwrap(); + Thread::scoped(move|| g() ).join().err().unwrap(); } pub fn main() { diff --git a/src/test/run-pass/threads.rs b/src/test/run-pass/threads.rs index 02817a285ddf5..c47ca0db2a156 100644 --- a/src/test/run-pass/threads.rs +++ b/src/test/run-pass/threads.rs @@ -13,7 +13,7 @@ use std::thread::Thread; pub fn main() { let mut i = 10; while i > 0 { - Thread::spawn({let i = i; move|| child(i)}).detach(); + Thread::spawn({let i = i; move|| child(i)}); i = i - 1; } println!("main thread exiting"); diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs index bd4143348b886..bb3019ede4b57 100644 --- a/src/test/run-pass/unique-send-2.rs +++ b/src/test/run-pass/unique-send-2.rs @@ -23,7 +23,7 @@ pub fn main() { let tx = tx.clone(); Thread::spawn(move|| { child(&tx, i) - }).detach(); + }); expected += i; } diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs index 9aeb5b10cf5f8..4c8665032828e 100644 --- a/src/test/run-pass/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/unit-like-struct-drop-run.rs @@ -22,7 +22,7 @@ impl Drop for Foo { } pub fn main() { - let x = Thread::spawn(move|| { + let x = Thread::scoped(move|| { let _b = Foo; }).join(); diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs index bdd62995e0a31..29bf82a81d65d 100644 --- a/src/test/run-pass/vector-sort-panic-safe.rs +++ b/src/test/run-pass/vector-sort-panic-safe.rs @@ -77,7 +77,7 @@ pub fn main() { let v = main.clone(); - let _ = Thread::spawn(move|| { + let _ = Thread::scoped(move|| { let mut v = v; let mut panic_countdown = panic_countdown; v.as_mut_slice().sort_by(|a, b| { diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 9a96b483f2c92..9ad6dd9d2b142 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -11,7 +11,7 @@ use std::thread::Thread; pub fn main() { - let mut result = Thread::spawn(child); + let mut result = Thread::scoped(child); println!("1"); Thread::yield_now(); println!("2"); diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 13119e5d909cd..3d3a36021da15 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -11,7 +11,7 @@ use std::thread::Thread; pub fn main() { - let mut result = Thread::spawn(child); + let mut result = Thread::scoped(child); println!("1"); Thread::yield_now(); result.join();