@@ -7,13 +7,17 @@ use crate::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
77use  crate :: sync:: atomic:: { AtomicUsize ,  Ordering } ; 
88use  crate :: sync:: { Arc ,  Mutex } ; 
99
10- /// TODO: documentation 
10+ /// A scope to spawn scoped threads in. 
11+ /// 
12+ /// See [`scope`] for details. 
1113pub  struct  Scope < ' env >  { 
1214    data :  ScopeData , 
1315    env :  PhantomData < & ' env  ( ) > , 
1416} 
1517
16- /// TODO: documentation 
18+ /// An owned permission to join on a scoped thread (block on its termination). 
19+ /// 
20+ /// See [`Scope::spawn`] for details. 
1721pub  struct  ScopedJoinHandle < ' scope ,  T > ( JoinInner < ' scope ,  T > ) ; 
1822
1923pub ( super )  struct  ScopeData  { 
@@ -39,7 +43,52 @@ impl ScopeData {
3943    } 
4044} 
4145
42- /// TODO: documentation 
46+ /// Create a scope for spawning scoped threads. 
47+ /// 
48+ /// The function passed to `scope` will be provided a [`Scope`] object, 
49+ /// through which scoped threads can be [spawned][`Scope::spawn`]. 
50+ /// 
51+ /// Unlike non-scoped threads, scoped threads can non-`'static` data, 
52+ /// as the scope guarantees all threads will be joined at the end of the scope. 
53+ /// 
54+ /// All threads spawned within the scope that haven't been manually joined 
55+ /// will be automatically joined before this function returns. 
56+ /// 
57+ /// # Panics 
58+ /// 
59+ /// If any of the automatically joined threads panicked, this function will panic. 
60+ /// 
61+ /// If you want to handle panics from spawned threads, 
62+ /// [`join`][ScopedJoinHandle::join] them before the end of the scope. 
63+ /// 
64+ /// # Example 
65+ /// 
66+ /// ``` 
67+ /// #![feature(scoped_threads)] 
68+ /// use std::thread; 
69+ /// 
70+ /// let mut a = vec![1, 2, 3]; 
71+ /// let mut x = 0; 
72+ /// 
73+ /// thread::scope(|s| { 
74+ ///     s.spawn(|_| { 
75+ ///         println!("hello from the first scoped thread"); 
76+ ///         // We can borrow `a` here. 
77+ ///         dbg!(&a); 
78+ ///     }); 
79+ ///     s.spawn(|_| { 
80+ ///         println!("hello from the second scoped thread"); 
81+ ///         // We can even mutably borrow `x` here, 
82+ ///         // because no other threads are using it. 
83+ ///         x += a[0] + a[2]; 
84+ ///     }); 
85+ ///     println!("hello from the main thread"); 
86+ /// }); 
87+ /// 
88+ /// // After the scope, we can modify and access our variables again: 
89+ /// a.push(4); 
90+ /// assert_eq!(x, a.len()); 
91+ /// ``` 
4392pub  fn  scope < ' env ,  F ,  T > ( f :  F )  -> T 
4493where 
4594    F :  FnOnce ( & Scope < ' env > )  -> T , 
@@ -80,7 +129,30 @@ where
80129} 
81130
82131impl < ' env >  Scope < ' env >  { 
83-     /// TODO: documentation 
132+     /// Spawns a new thread within a scope, returning a [`ScopedJoinHandle`] for it. 
133+ /// 
134+ /// Unlike non-scoped threads, threads spawned with this function may 
135+ /// borrow non-`'static` data from the outside the scope. See [`scope`] for 
136+ /// details. 
137+ /// 
138+ /// The join handle provides a [`join`] method that can be used to join the spawned 
139+ /// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing 
140+ /// the panic payload. 
141+ /// 
142+ /// If the join handle is dropped, the spawned thread will implicitly joined at the 
143+ /// end of the scope. In that case, if the spawned thread panics, [`scope`] will 
144+ /// panic after all threads are joined. 
145+ /// 
146+ /// This call will create a thread using default parameters of [`Builder`]. 
147+ /// If you want to specify the stack size or the name of the thread, use 
148+ /// [`Builder::spawn_scoped`] instead. 
149+ /// 
150+ /// # Panics 
151+ /// 
152+ /// Panics if the OS fails to create a thread; use [`Builder::spawn`] 
153+ /// to recover from such errors. 
154+ /// 
155+ /// [`join`]: ScopedJoinHandle::join 
84156pub  fn  spawn < ' scope ,  F ,  T > ( & ' scope  self ,  f :  F )  -> ScopedJoinHandle < ' scope ,  T > 
85157    where 
86158        F :  FnOnce ( & Scope < ' env > )  -> T  + Send  + ' env , 
@@ -91,7 +163,54 @@ impl<'env> Scope<'env> {
91163} 
92164
93165impl  Builder  { 
94-     fn  spawn_scoped < ' scope ,  ' env ,  F ,  T > ( 
166+     /// Spawns a new scoped thread using the settings set through this `Builder`. 
167+ /// 
168+ /// Unlike [`Scope::spawn`], this method yields an [`io::Result`] to 
169+ /// capture any failure to create the thread at the OS level. 
170+ /// 
171+ /// [`io::Result`]: crate::io::Result 
172+ /// 
173+ /// # Panics 
174+ /// 
175+ /// Panics if a thread name was set and it contained null bytes. 
176+ /// 
177+ /// # Example 
178+ /// 
179+ /// ``` 
180+ /// #![feature(scoped_threads)] 
181+ /// use std::thread; 
182+ /// 
183+ /// let mut a = vec![1, 2, 3]; 
184+ /// let mut x = 0; 
185+ /// 
186+ /// thread::scope(|s| { 
187+ ///     thread::Builder::new() 
188+ ///         .name("first".to_string()) 
189+ ///         .spawn_scoped(s, |_| 
190+ ///     { 
191+ ///         println!("hello from the {:?} scoped thread", thread::current().name()); 
192+ ///         // We can borrow `a` here. 
193+ ///         dbg!(&a); 
194+ ///     }) 
195+ ///     .unwrap(); 
196+ ///     thread::Builder::new() 
197+ ///         .name("second".to_string()) 
198+ ///         .spawn_scoped(s, |_| 
199+ ///     { 
200+ ///         println!("hello from the {:?} scoped thread", thread::current().name()); 
201+ ///         // We can even mutably borrow `x` here, 
202+ ///         // because no other threads are using it. 
203+ ///         x += a[0] + a[2]; 
204+ ///     }) 
205+ ///     .unwrap(); 
206+ ///     println!("hello from the main thread"); 
207+ /// }); 
208+ /// 
209+ /// // After the scope, we can modify and access our variables again: 
210+ /// a.push(4); 
211+ /// assert_eq!(x, a.len()); 
212+ /// ``` 
213+ pub  fn  spawn_scoped < ' scope ,  ' env ,  F ,  T > ( 
95214        self , 
96215        scope :  & ' scope  Scope < ' env > , 
97216        f :  F , 
@@ -105,16 +224,61 @@ impl Builder {
105224} 
106225
107226impl < ' scope ,  T >  ScopedJoinHandle < ' scope ,  T >  { 
108-     /// TODO 
109- pub  fn  join ( self )  -> Result < T >  { 
110-         self . 0 . join ( ) 
111-     } 
112- 
113-     /// TODO 
227+     /// Extracts a handle to the underlying thread. 
228+ /// 
229+ /// # Examples 
230+ /// 
231+ /// ``` 
232+ /// #![feature(scoped_threads)] 
233+ /// #![feature(thread_is_running)] 
234+ /// 
235+ /// use std::thread; 
236+ /// 
237+ /// thread::scope(|s| { 
238+ ///     let t = s.spawn(|_| { 
239+ ///         println!("hello"); 
240+ ///     }); 
241+ ///     println!("thread id: {:?}", t.thread().id()); 
242+ /// }); 
243+ /// ``` 
244+ #[ must_use]  
114245    pub  fn  thread ( & self )  -> & Thread  { 
115246        & self . 0 . thread 
116247    } 
117248
249+     /// Waits for the associated thread to finish. 
250+ /// 
251+ /// This function will return immediately if the associated thread has already finished. 
252+ /// 
253+ /// In terms of [atomic memory orderings], the completion of the associated 
254+ /// thread synchronizes with this function returning. 
255+ /// In other words, all operations performed by that thread 
256+ /// [happen before](https://doc.rust-lang.org/nomicon/atomics.html#data-accesses) 
257+ /// all operations that happen after `join` returns. 
258+ /// 
259+ /// If the associated thread panics, [`Err`] is returned with the panic payload. 
260+ /// 
261+ /// [atomic memory orderings]: crate::sync::atomic 
262+ /// 
263+ /// # Examples 
264+ /// 
265+ /// ``` 
266+ /// #![feature(scoped_threads)] 
267+ /// #![feature(thread_is_running)] 
268+ /// 
269+ /// use std::thread; 
270+ /// 
271+ /// thread::scope(|s| { 
272+ ///     let t = s.spawn(|_| { 
273+ ///         panic!("oh no"); 
274+ ///     }); 
275+ ///     assert!(t.join().is_err()); 
276+ /// }); 
277+ /// ``` 
278+ pub  fn  join ( self )  -> Result < T >  { 
279+         self . 0 . join ( ) 
280+     } 
281+ 
118282    /// Checks if the the associated thread is still running its main function. 
119283/// 
120284/// This might return `false` for a brief moment after the thread's main 
0 commit comments