1616//! each with their own stack and local state.
1717//!
1818//! Communication between threads can be done through
19- //! [channels](../../std/comm /index.html), Rust's message-passing
19+ //! [channels](../../std/sync/mpsc /index.html), Rust's message-passing
2020//! types, along with [other forms of thread
2121//! synchronization](../../std/sync/index.html) and shared-memory data
2222//! structures. In particular, types that are guaranteed to be
5858//! ```rust
5959//! use std::thread::Thread;
6060//!
61- //! let guard = Thread::spawn(move || {
61+ //! let thread = Thread::spawn(move || {
6262//! println!("Hello, World!");
6363//! // some computation here
6464//! });
65- //! let result = guard.join();
6665//! ```
6766//!
68- //! The `spawn` function doesn't return a `Thread` directly; instead, it returns
69- //! a *join guard* from which a `Thread` can be extracted. The join guard is an
70- //! RAII-style guard that will automatically join the child thread (block until
71- //! it terminates) when it is dropped. You can join the child thread in advance
72- //! by calling the `join` method on the guard, which will also return the result
73- //! produced by the thread.
67+ //! The spawned thread is "detached" from the current thread, meaning that it
68+ //! can outlive the thread that spawned it. (Note, however, that when the main
69+ //! thread terminates all detached threads are terminated as well.) The returned
70+ //! `Thread` handle can be used for low-level synchronization as described below.
71+ //!
72+ //! ## Scoped threads
73+ //!
74+ //! Often a parent thread uses a child thread to perform some particular task,
75+ //! and at some point must wait for the child to complete before continuing.
76+ //! For this scenario, use the `scoped` constructor:
77+ //!
78+ //! ```rust
79+ //! use std::thread::Thread;
80+ //!
81+ //! let guard = Thread::scoped(move || {
82+ //! println!("Hello, World!");
83+ //! // some computation here
84+ //! });
85+ //! // do some other work in the meantime
86+ //! let result = guard.join();
87+ //! ```
7488//!
75- //! If you instead wish to *detach* the child thread, allowing it to outlive its
76- //! parent, you can use the `detach` method on the guard,
89+ //! The `scoped` function doesn't return a `Thread` directly; instead, it
90+ //! returns a *join guard* from which a `Thread` can be extracted. The join
91+ //! guard is an RAII-style guard that will automatically join the child thread
92+ //! (block until it terminates) when it is dropped. You can join the child
93+ //! thread in advance by calling the `join` method on the guard, which will also
94+ //! return the result produced by the thread. A handle to the thread itself is
95+ //! available via the `thread` method on the join guard.
7796//!
78- //! A handle to the thread itself is available via the `thread` method on the
79- //! join guard.
97+ //! (Note: eventually, the `scoped` constructor will allow the parent and child
98+ //! threads to data that lives on the parent thread's stack, but some language
99+ //! changes are needed before this is possible.)
80100//!
81101//! ## Configuring threads
82102//!
89109//!
90110//! thread::Builder::new().name("child1".to_string()).spawn(move || {
91111//! println!("Hello, world!")
92- //! }).detach() ;
112+ //! });
93113//! ```
94114//!
95115//! ## Blocking support: park and unpark
124144//!
125145//! * It can be implemented highly efficiently on many platforms.
126146
147+ #![ stable]
148+
127149use any:: Any ;
128150use boxed:: Box ;
129151use cell:: UnsafeCell ;
@@ -144,6 +166,7 @@ use sys_common::{stack, thread_info};
144166
145167/// Thread configuation. Provides detailed control over the properties
146168/// and behavior of new threads.
169+ #[ stable]
147170pub struct Builder {
148171 // A name for the thread-to-be, for identification in panic messages
149172 name : Option < String > ,
@@ -158,6 +181,7 @@ pub struct Builder {
158181impl Builder {
159182 /// Generate the base configuration for spawning a thread, from which
160183 /// configuration methods can be chained.
184+ #[ stable]
161185 pub fn new ( ) -> Builder {
162186 Builder {
163187 name : None ,
@@ -169,12 +193,14 @@ impl Builder {
169193
170194 /// Name the thread-to-be. Currently the name is used for identification
171195 /// only in panic messages.
196+ #[ stable]
172197 pub fn name ( mut self , name : String ) -> Builder {
173198 self . name = Some ( name) ;
174199 self
175200 }
176201
177202 /// Set the size of the stack for the new thread.
203+ #[ stable]
178204 pub fn stack_size ( mut self , size : uint ) -> Builder {
179205 self . stack_size = Some ( size) ;
180206 self
@@ -194,19 +220,41 @@ impl Builder {
194220 self
195221 }
196222
197- /// Spawn a new joinable thread, and return a JoinGuard guard for it.
223+ /// Spawn a new detached thread, and return a handle to it.
198224 ///
199225 /// See `Thead::spawn` and the module doc for more details.
200- pub fn spawn < T , F > ( self , f : F ) -> JoinGuard < T > where
201- T : Send , F : FnOnce ( ) -> T , F : Send
202- {
203- self . spawn_inner ( Thunk :: new ( f) )
226+ #[ unstable = "may change with specifics of new Send semantics" ]
227+ pub fn spawn < F > ( self , f : F ) -> Thread where F : FnOnce ( ) , F : Send + ' static {
228+ let ( native, thread) = self . spawn_inner ( Thunk :: new ( f) , Thunk :: with_arg ( |_| { } ) ) ;
229+ unsafe { imp:: detach ( native) } ;
230+ thread
204231 }
205232
206- fn spawn_inner < T : Send > ( self , f : Thunk < ( ) , T > ) -> JoinGuard < T > {
233+ /// Spawn a new child thread that must be joined within a given
234+ /// scope, and return a `JoinGuard`.
235+ ///
236+ /// See `Thead::scoped` and the module doc for more details.
237+ #[ unstable = "may change with specifics of new Send semantics" ]
238+ pub fn scoped < ' a , T , F > ( self , f : F ) -> JoinGuard < ' a , T > where
239+ T : Send + ' a , F : FnOnce ( ) -> T , F : Send + ' a
240+ {
207241 let my_packet = Packet ( Arc :: new ( UnsafeCell :: new ( None ) ) ) ;
208242 let their_packet = Packet ( my_packet. 0 . clone ( ) ) ;
243+ let ( native, thread) = self . spawn_inner ( Thunk :: new ( f) , Thunk :: with_arg ( move |: ret| unsafe {
244+ * their_packet. 0 . get ( ) = Some ( ret) ;
245+ } ) ) ;
209246
247+ JoinGuard {
248+ native : native,
249+ joined : false ,
250+ packet : my_packet,
251+ thread : thread,
252+ }
253+ }
254+
255+ fn spawn_inner < T : Send > ( self , f : Thunk < ( ) , T > , finish : Thunk < Result < T > , ( ) > )
256+ -> ( imp:: rust_thread , Thread )
257+ {
210258 let Builder { name, stack_size, stdout, stderr } = self ;
211259
212260 let stack_size = stack_size. unwrap_or ( rt:: min_stack ( ) ) ;
@@ -258,21 +306,14 @@ impl Builder {
258306 unwind:: try ( move || * ptr = Some ( f. invoke ( ( ) ) ) )
259307 }
260308 } ;
261- unsafe {
262- * their_packet. 0 . get ( ) = Some ( match ( output, try_result) {
263- ( Some ( data) , Ok ( _) ) => Ok ( data) ,
264- ( None , Err ( cause) ) => Err ( cause) ,
265- _ => unreachable ! ( )
266- } ) ;
267- }
309+ finish. invoke ( match ( output, try_result) {
310+ ( Some ( data) , Ok ( _) ) => Ok ( data) ,
311+ ( None , Err ( cause) ) => Err ( cause) ,
312+ _ => unreachable ! ( )
313+ } ) ;
268314 } ;
269315
270- JoinGuard {
271- native : unsafe { imp:: create ( stack_size, Thunk :: new ( main) ) } ,
272- joined : false ,
273- packet : my_packet,
274- thread : my_thread,
275- }
316+ ( unsafe { imp:: create ( stack_size, Thunk :: new ( main) ) } , my_thread)
276317 }
277318}
278319
@@ -285,11 +326,13 @@ struct Inner {
285326unsafe impl Sync for Inner { }
286327
287328#[ derive( Clone ) ]
329+ #[ stable]
288330/// A handle to a thread.
289331pub struct Thread {
290332 inner : Arc < Inner > ,
291333}
292334
335+ #[ stable]
293336unsafe impl Sync for Thread { }
294337
295338impl Thread {
@@ -304,30 +347,47 @@ impl Thread {
304347 }
305348 }
306349
307- /// Spawn a new joinable thread, returning a `JoinGuard` for it.
350+ /// Spawn a new detached thread, returning a handle to it.
351+ ///
352+ /// The child thread may outlive the parent (unless the parent thread is the
353+ /// main thread; the whole process is terminated when the main thread
354+ /// finishes.) The thread handle can be used for low-level
355+ /// synchronization. See the module documentation for additional details.
356+ #[ unstable = "may change with specifics of new Send semantics" ]
357+ pub fn spawn < F > ( f : F ) -> Thread where F : FnOnce ( ) , F : Send + ' static {
358+ Builder :: new ( ) . spawn ( f)
359+ }
360+
361+ /// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
308362 ///
309363 /// The join guard can be used to explicitly join the child thread (via
310364 /// `join`), returning `Result<T>`, or it will implicitly join the child
311- /// upon being dropped. To detach the child, allowing it to outlive the
312- /// current thread, use `detach`. See the module documentation for additional details.
313- pub fn spawn < T , F > ( f : F ) -> JoinGuard < T > where
314- T : Send , F : FnOnce ( ) -> T , F : Send
365+ /// upon being dropped. Because the child thread may refer to data on the
366+ /// current thread's stack (hence the "scoped" name), it cannot be detached;
367+ /// it *must* be joined before the relevant stack frame is popped. See the
368+ /// module documentation for additional details.
369+ #[ unstable = "may change with specifics of new Send semantics" ]
370+ pub fn scoped < ' a , T , F > ( f : F ) -> JoinGuard < ' a , T > where
371+ T : Send + ' a , F : FnOnce ( ) -> T , F : Send + ' a
315372 {
316- Builder :: new ( ) . spawn ( f)
373+ Builder :: new ( ) . scoped ( f)
317374 }
318375
319376 /// Gets a handle to the thread that invokes it.
377+ #[ stable]
320378 pub fn current ( ) -> Thread {
321379 thread_info:: current_thread ( )
322380 }
323381
324382 /// Cooperatively give up a timeslice to the OS scheduler.
383+ #[ unstable = "name may change" ]
325384 pub fn yield_now ( ) {
326385 unsafe { imp:: yield_now ( ) }
327386 }
328387
329388 /// Determines whether the current thread is panicking.
330389 #[ inline]
390+ #[ stable]
331391 pub fn panicking ( ) -> bool {
332392 unwind:: panicking ( )
333393 }
@@ -341,6 +401,7 @@ impl Thread {
341401 // future, this will be implemented in a more efficient way, perhaps along the lines of
342402 // http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
343403 // or futuxes, and in either case may allow spurious wakeups.
404+ #[ unstable = "recently introduced" ]
344405 pub fn park ( ) {
345406 let thread = Thread :: current ( ) ;
346407 let mut guard = thread. inner . lock . lock ( ) . unwrap ( ) ;
@@ -353,6 +414,7 @@ impl Thread {
353414 /// Atomically makes the handle's token available if it is not already.
354415 ///
355416 /// See the module doc for more detail.
417+ #[ unstable = "recently introduced" ]
356418 pub fn unpark ( & self ) {
357419 let mut guard = self . inner . lock . lock ( ) . unwrap ( ) ;
358420 if !* guard {
@@ -362,6 +424,7 @@ impl Thread {
362424 }
363425
364426 /// Get the thread's name.
427+ #[ stable]
365428 pub fn name ( & self ) -> Option < & str > {
366429 self . inner . name . as_ref ( ) . map ( |s| s. as_slice ( ) )
367430 }
@@ -375,28 +438,32 @@ impl thread_info::NewThread for Thread {
375438/// Indicates the manner in which a thread exited.
376439///
377440/// A thread that completes without panicking is considered to exit successfully.
441+ #[ stable]
378442pub type Result < T > = :: result:: Result < T , Box < Any + Send > > ;
379443
380444struct Packet < T > ( Arc < UnsafeCell < Option < Result < T > > > > ) ;
381445
382446unsafe impl < T : ' static +Send > Send for Packet < T > { }
383447unsafe impl < T > Sync for Packet < T > { }
384448
385- #[ must_use]
386449/// An RAII-style guard that will block until thread termination when dropped.
387450///
388451/// The type `T` is the return type for the thread's main function.
389- pub struct JoinGuard < T > {
452+ #[ must_use]
453+ #[ unstable = "may change with specifics of new Send semantics" ]
454+ pub struct JoinGuard < ' a , T : ' a > {
390455 native : imp:: rust_thread ,
391456 thread : Thread ,
392457 joined : bool ,
393458 packet : Packet < T > ,
394459}
395460
396- unsafe impl < T : Send > Sync for JoinGuard < T > { }
461+ #[ stable]
462+ unsafe impl < ' a , T : Send + ' a > Sync for JoinGuard < ' a , T > { }
397463
398- impl < T : Send > JoinGuard < T > {
464+ impl < ' a , T : Send + ' a > JoinGuard < ' a , T > {
399465 /// Extract a handle to the thread this guard will join on.
466+ #[ stable]
400467 pub fn thread ( & self ) -> & Thread {
401468 & self . thread
402469 }
@@ -406,6 +473,7 @@ impl<T: Send> JoinGuard<T> {
406473 ///
407474 /// If the child thread panics, `Err` is returned with the parameter given
408475 /// to `panic`.
476+ #[ stable]
409477 pub fn join ( mut self ) -> Result < T > {
410478 assert ! ( !self . joined) ;
411479 unsafe { imp:: join ( self . native ) } ;
@@ -414,8 +482,11 @@ impl<T: Send> JoinGuard<T> {
414482 ( * self . packet . 0 . get ( ) ) . take ( ) . unwrap ( )
415483 }
416484 }
485+ }
417486
487+ impl < T : Send > JoinGuard < ' static , T > {
418488 /// Detaches the child thread, allowing it to outlive its parent.
489+ #[ experimental = "unsure whether this API imposes limitations elsewhere" ]
419490 pub fn detach ( mut self ) {
420491 unsafe { imp:: detach ( self . native ) } ;
421492 self . joined = true ; // avoid joining in the destructor
@@ -424,7 +495,7 @@ impl<T: Send> JoinGuard<T> {
424495
425496#[ unsafe_destructor]
426497#[ stable]
427- impl < T : Send > Drop for JoinGuard < T > {
498+ impl < ' a , T : Send + ' a > Drop for JoinGuard < ' a , T > {
428499 fn drop ( & mut self ) {
429500 if !self . joined {
430501 unsafe { imp:: join ( self . native ) } ;
0 commit comments