67
67
//! thread. This means that it can outlive its parent (the thread that spawned
68
68
//! it), unless this parent is the main thread.
69
69
//!
70
+ //! The parent thread can also wait on the completion of the child
71
+ //! thread; a call to `spawn` produces a `JoinHandle`, which provides
72
+ //! a `join` method for waiting:
73
+ //!
74
+ //! ```rust
75
+ //! use std::thread;
76
+ //!
77
+ //! let child = thread::spawn(move || {
78
+ //! // some work here
79
+ //! });
80
+ //! // some work here
81
+ //! let res = child.join();
82
+ //! ```
83
+ //!
84
+ //! The `join` method returns a `Result` containing `Ok` of the final
85
+ //! value produced by the child thread, or `Err` of the value given to
86
+ //! a call to `panic!` if the child panicked.
87
+ //!
70
88
//! ## Scoped threads
71
89
//!
72
- //! Often a parent thread uses a child thread to perform some particular task,
73
- //! and at some point must wait for the child to complete before continuing.
74
- //! For this scenario, use the `thread::scoped` function:
90
+ //! The `spawn` method does not allow the child and parent threads to
91
+ //! share any stack data, since that is not safe in general. However,
92
+ //! `scoped` makes it possible to share the parent's stack by forcing
93
+ //! a join before any relevant stack frames are popped:
75
94
//!
76
95
//! ```rust
77
96
//! use std::thread;
@@ -253,8 +272,8 @@ impl Builder {
253
272
/// `io::Result` to capture any failure to create the thread at
254
273
/// the OS level.
255
274
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
256
- pub fn spawn < F > ( self , f : F ) -> io:: Result < JoinHandle > where
257
- F : FnOnce ( ) , F : Send + ' static
275
+ pub fn spawn < F , T > ( self , f : F ) -> io:: Result < JoinHandle < T > > where
276
+ F : FnOnce ( ) -> T , F : Send + ' static , T : Send + ' static
258
277
{
259
278
self . spawn_inner ( Box :: new ( f) ) . map ( |i| JoinHandle ( i) )
260
279
}
@@ -371,7 +390,9 @@ impl Builder {
371
390
/// Panics if the OS fails to create a thread; use `Builder::spawn`
372
391
/// to recover from such errors.
373
392
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
374
- pub fn spawn < F > ( f : F ) -> JoinHandle where F : FnOnce ( ) , F : Send + ' static {
393
+ pub fn spawn < F , T > ( f : F ) -> JoinHandle < T > where
394
+ F : FnOnce ( ) -> T , F : Send + ' static , T : Send + ' static
395
+ {
375
396
Builder :: new ( ) . spawn ( f) . unwrap ( )
376
397
}
377
398
@@ -637,9 +658,9 @@ impl<T> JoinInner<T> {
637
658
/// handle: the ability to join a child thread is a uniquely-owned
638
659
/// permission.
639
660
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
640
- pub struct JoinHandle ( JoinInner < ( ) > ) ;
661
+ pub struct JoinHandle < T > ( JoinInner < T > ) ;
641
662
642
- impl JoinHandle {
663
+ impl < T > JoinHandle < T > {
643
664
/// Extract a handle to the underlying thread
644
665
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
645
666
pub fn thread ( & self ) -> & Thread {
@@ -651,13 +672,14 @@ impl JoinHandle {
651
672
/// If the child thread panics, `Err` is returned with the parameter given
652
673
/// to `panic`.
653
674
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
654
- pub fn join ( mut self ) -> Result < ( ) > {
675
+ pub fn join ( mut self ) -> Result < T > {
655
676
self . 0 . join ( )
656
677
}
657
678
}
658
679
659
680
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
660
- impl Drop for JoinHandle {
681
+ #[ unsafe_destructor]
682
+ impl < T > Drop for JoinHandle < T > {
661
683
fn drop ( & mut self ) {
662
684
if !self . 0 . joined {
663
685
unsafe { imp:: detach ( self . 0 . native ) }
0 commit comments