11use std:: cell:: Cell ;
2- use std:: fmt:: Arguments ;
3- use std:: mem;
42use std:: ptr;
53use std:: thread;
64
75use crossbeam_channel:: { unbounded, Sender } ;
86use lazy_static:: lazy_static;
97
8+ use super :: log_utils;
109use super :: task;
1110use super :: { JoinHandle , Task } ;
1211use crate :: future:: Future ;
1312use crate :: io;
13+ use crate :: utils:: abort_on_panic;
1414
1515/// Returns a handle to the current task.
1616///
6464 F : Future < Output = T > + Send + ' static ,
6565 T : Send + ' static ,
6666{
67- spawn_with_builder ( Builder :: new ( ) , future, "spawn" )
67+ spawn_with_builder ( Builder :: new ( ) , future)
6868}
6969
7070/// Task builder that configures the settings of a new task.
@@ -91,15 +91,11 @@ impl Builder {
9191 F : Future < Output = T > + Send + ' static ,
9292 T : Send + ' static ,
9393 {
94- Ok ( spawn_with_builder ( self , future, "spawn" ) )
94+ Ok ( spawn_with_builder ( self , future) )
9595 }
9696}
9797
98- pub ( crate ) fn spawn_with_builder < F , T > (
99- builder : Builder ,
100- future : F ,
101- fn_name : & ' static str ,
102- ) -> JoinHandle < T >
98+ pub ( crate ) fn spawn_with_builder < F , T > ( builder : Builder , future : F ) -> JoinHandle < T >
10399where
104100 F : Future < Output = T > + Send + ' static ,
105101 T : Send + ' static ,
@@ -117,13 +113,9 @@ where
117113 thread:: Builder :: new( )
118114 . name( "async-task-driver" . to_string( ) )
119115 . spawn( || {
120- TAG . with( |tag| {
121- for job in receiver {
122- tag. set( job. tag( ) ) ;
123- abort_on_panic( || job. run( ) ) ;
124- tag. set( ptr:: null( ) ) ;
125- }
126- } ) ;
116+ for job in receiver {
117+ set_tag( job. tag( ) , || abort_on_panic( || job. run( ) ) )
118+ }
127119 } )
128120 . expect( "cannot start a thread driving tasks" ) ;
129121 }
@@ -135,11 +127,12 @@ where
135127 let tag = task:: Tag :: new ( name) ;
136128 let schedule = |job| QUEUE . send ( job) . unwrap ( ) ;
137129
130+ // Log this `spawn` operation.
138131 let child_id = tag. task_id ( ) . as_u64 ( ) ;
139132 let parent_id = get_task ( |t| t. id ( ) . as_u64 ( ) ) . unwrap_or ( 0 ) ;
140- print (
141- format_args ! ( "{}" , fn_name ) ,
142- LogData {
133+ log_utils :: print (
134+ format_args ! ( "spawn" ) ,
135+ log_utils :: LogData {
143136 parent_id,
144137 child_id,
145138 } ,
@@ -152,9 +145,9 @@ where
152145 // Abort on panic because thread-local variables behave the same way.
153146 abort_on_panic ( || get_task ( |task| task. metadata ( ) . local_map . clear ( ) ) ) ;
154147
155- print (
156- format_args ! ( "{} completed" , fn_name ) ,
157- LogData {
148+ log_utils :: print (
149+ format_args ! ( "spawn completed" ) ,
150+ log_utils :: LogData {
158151 parent_id,
159152 child_id,
160153 } ,
@@ -171,61 +164,34 @@ thread_local! {
171164 static TAG : Cell <* const task:: Tag > = Cell :: new( ptr:: null_mut( ) ) ;
172165}
173166
174- pub ( crate ) fn get_task < F : FnOnce ( & Task ) -> R , R > ( f : F ) -> Option < R > {
175- let res = TAG . try_with ( |tag| unsafe { tag. get ( ) . as_ref ( ) . map ( task:: Tag :: task) . map ( f) } ) ;
176-
177- match res {
178- Ok ( Some ( val) ) => Some ( val) ,
179- Ok ( None ) | Err ( _) => None ,
180- }
181- }
182-
183- /// Calls a function and aborts if it panics.
184- ///
185- /// This is useful in unsafe code where we can't recover from panics.
186- #[ inline]
187- fn abort_on_panic < T > ( f : impl FnOnce ( ) -> T ) -> T {
188- struct Bomb ;
167+ pub ( crate ) fn set_tag < F , R > ( tag : * const task:: Tag , f : F ) -> R
168+ where
169+ F : FnOnce ( ) -> R ,
170+ {
171+ struct ResetTag < ' a > ( & ' a Cell < * const task:: Tag > ) ;
189172
190- impl Drop for Bomb {
173+ impl Drop for ResetTag < ' _ > {
191174 fn drop ( & mut self ) {
192- std :: process :: abort ( ) ;
175+ self . 0 . set ( ptr :: null ( ) ) ;
193176 }
194177 }
195178
196- let bomb = Bomb ;
197- let t = f ( ) ;
198- mem:: forget ( bomb) ;
199- t
200- }
179+ TAG . with ( |t| {
180+ t. set ( tag) ;
181+ let _guard = ResetTag ( t) ;
201182
202- /// This struct only exists because kv logging isn't supported from the macros right now.
203- struct LogData {
204- parent_id : u64 ,
205- child_id : u64 ,
183+ f ( )
184+ } )
206185}
207186
208- impl < ' a > log:: kv:: Source for LogData {
209- fn visit < ' kvs > (
210- & ' kvs self ,
211- visitor : & mut dyn log:: kv:: Visitor < ' kvs > ,
212- ) -> Result < ( ) , log:: kv:: Error > {
213- visitor. visit_pair ( "parent_id" . into ( ) , self . parent_id . into ( ) ) ?;
214- visitor. visit_pair ( "child_id" . into ( ) , self . child_id . into ( ) ) ?;
215- Ok ( ( ) )
216- }
217- }
187+ pub ( crate ) fn get_task < F , R > ( f : F ) -> Option < R >
188+ where
189+ F : FnOnce ( & Task ) -> R ,
190+ {
191+ let res = TAG . try_with ( |tag| unsafe { tag. get ( ) . as_ref ( ) . map ( task:: Tag :: task) . map ( f) } ) ;
218192
219- fn print ( msg : Arguments < ' _ > , key_values : impl log:: kv:: Source ) {
220- log:: logger ( ) . log (
221- & log:: Record :: builder ( )
222- . args ( msg)
223- . key_values ( & key_values)
224- . level ( log:: Level :: Trace )
225- . target ( module_path ! ( ) )
226- . module_path ( Some ( module_path ! ( ) ) )
227- . file ( Some ( file ! ( ) ) )
228- . line ( Some ( line ! ( ) ) )
229- . build ( ) ,
230- ) ;
193+ match res {
194+ Ok ( Some ( val) ) => Some ( val) ,
195+ Ok ( None ) | Err ( _) => None ,
196+ }
231197}
0 commit comments