@@ -143,6 +143,7 @@ impl Builder {
143143 }
144144
145145 let task = Task ( Arc :: new ( Inner {
146+ id : TaskId :: new ( ) ,
146147 name : self . name . take ( ) ,
147148 locals : RefCell :: new ( HashMap :: default ( ) ) ,
148149 } ) ) ;
@@ -176,9 +177,10 @@ impl Builder {
176177///
177178/// # Panics
178179///
179- /// This function will panic if not called within the context of a task spawned by [`spawn`] or
180- /// [`Builder::spawn`].
180+ /// This function will panic if not called within the context of a task created by [`block_on`],
181+ /// [`spawn`], or [` Builder::spawn`].
181182///
183+ /// [`block_on`]: fn.block_on.html
182184/// [`spawn`]: fn.spawn.html
183185/// [`Builder::spawn`]: struct.Builder.html#method.spawn
184186///
@@ -195,7 +197,7 @@ pub fn current() -> Task {
195197 TASK . with ( |task| {
196198 let raw = task
197199 . get ( )
198- . expect ( "`task::current()` called outside the context of a spawned task" ) ;
200+ . expect ( "`task::current()` called outside the context of a task" ) ;
199201 unsafe { Task :: clone ( & * raw) }
200202 } )
201203}
@@ -211,6 +213,7 @@ thread_local! {
211213pub struct Task ( Arc < Inner > ) ;
212214
213215struct Inner {
216+ id : TaskId ,
214217 name : Option < String > ,
215218 locals : LocalMap ,
216219}
@@ -219,6 +222,11 @@ unsafe impl Send for Inner {}
219222unsafe impl Sync for Inner { }
220223
221224impl Task {
225+ /// Gets the task's unique identifier.
226+ pub fn id ( & self ) -> TaskId {
227+ self . 0 . id
228+ }
229+
222230 /// Returns the name of this task.
223231 ///
224232 /// The name is configured by [`Builder::name`] before spawning.
@@ -235,6 +243,40 @@ impl fmt::Debug for Task {
235243 }
236244}
237245
246+ /// A unique identifier for a task.
247+ ///
248+ /// # Examples
249+ ///
250+ /// ```
251+ /// # #![feature(async_await)]
252+ /// use async_std::task;
253+ ///
254+ /// # async_std::task::block_on(async {
255+ /// task::block_on(async {
256+ /// println!("id = {:?}", task::current().id());
257+ /// })
258+ /// # });
259+ /// ```
260+ #[ derive( Eq , PartialEq , Clone , Copy , Hash , Debug ) ]
261+ pub struct TaskId ( u64 ) ;
262+
263+ impl TaskId {
264+ fn new ( ) -> TaskId {
265+ use std:: i64;
266+ use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
267+
268+ static COUNTER : AtomicU64 = AtomicU64 :: new ( 1 ) ;
269+
270+ let id = COUNTER . fetch_add ( 1 , Ordering :: Relaxed ) ;
271+ if id > i64:: MAX as u64 {
272+ unsafe {
273+ libc:: abort ( ) ;
274+ }
275+ }
276+ TaskId ( id)
277+ }
278+ }
279+
238280/// Declares task-local values.
239281///
240282/// The macro wraps any number of static declarations and makes them task-local. Attributes and
@@ -306,9 +348,10 @@ impl<T: Send + 'static> LocalKey<T> {
306348 ///
307349 /// # Panics
308350 ///
309- /// This method will panic if not called within the context of a task spawned by [`spawn`] or
310- /// [`Builder::spawn`].
351+ /// This function will panic if not called within the context of a task created by
352+ /// [`block_on`], [`spawn`], or [` Builder::spawn`].
311353 ///
354+ /// [`block_on`]: fn.block_on.html
312355 /// [`spawn`]: fn.spawn.html
313356 /// [`Builder::spawn`]: struct.Builder.html#method.spawn
314357 ///
0 commit comments