@@ -27,6 +27,7 @@ use super::local_heap::LocalHeap;
27
27
use rt:: sched:: { Scheduler , SchedHandle } ;
28
28
use rt:: stack:: { StackSegment , StackPool } ;
29
29
use rt:: context:: Context ;
30
+ use unstable:: finally:: Finally ;
30
31
use task:: spawn:: Taskgroup ;
31
32
use cell:: Cell ;
32
33
@@ -211,40 +212,34 @@ impl Task {
211
212
212
213
pub fn run ( & mut self , f : & fn ( ) ) {
213
214
rtdebug ! ( "run called on task: %u" , borrow:: to_uint( self ) ) ;
214
- self . unwinder . try ( f) ;
215
- // FIXME(#7544): We pass the taskgroup into death so that it can be
216
- // dropped while the unkillable counter is set. This should not be
217
- // necessary except for an extraneous clone() in task/spawn.rs that
218
- // causes a killhandle to get dropped, which mustn't receive a kill
219
- // signal since we're outside of the unwinder's try() scope.
220
- // { let _ = self.taskgroup.take(); }
221
- self . death . collect_failure ( !self . unwinder . unwinding , self . taskgroup . take ( ) ) ;
222
- self . destroy ( ) ;
223
- }
224
215
225
- /// must be called manually before finalization to clean up
226
- /// thread-local resources. Some of the routines here expect
227
- /// Task to be available recursively so this must be
228
- /// called unsafely, without removing Task from
229
- /// thread-local-storage.
230
- fn destroy( & mut self ) {
216
+ // The only try/catch block in the world. Attempt to run the task's
217
+ // client-specified code and catch any failures.
218
+ do self. unwinder . try {
231
219
232
- rtdebug ! ( "DESTROYING TASK: %u" , borrow:: to_uint( self ) ) ;
220
+ // Run the task main function, then do some cleanup.
221
+ do f. finally {
233
222
234
- do Local :: borrow :: < Task , ( ) > |task| {
235
- assert ! ( borrow:: ref_eq( task, self ) ) ;
236
- }
223
+ // Destroy task-local storage. This may run user dtors.
224
+ match self . storage {
225
+ LocalStorage ( ptr, Some ( ref dtor) ) => {
226
+ ( * dtor) ( ptr)
227
+ }
228
+ _ => ( )
229
+ }
237
230
238
- match self . storage {
239
- LocalStorage ( ptr, Some ( ref dtor) ) => {
240
- ( * dtor) ( ptr)
231
+ // Destroy remaining boxes. Also may run user dtors.
232
+ unsafe { cleanup:: annihilate ( ) ; }
241
233
}
242
- _ => ( )
243
234
}
244
235
245
- // Destroy remaining boxes
246
- unsafe { cleanup:: annihilate ( ) ; }
247
-
236
+ // FIXME(#7544): We pass the taskgroup into death so that it can be
237
+ // dropped while the unkillable counter is set. This should not be
238
+ // necessary except for an extraneous clone() in task/spawn.rs that
239
+ // causes a killhandle to get dropped, which mustn't receive a kill
240
+ // signal since we're outside of the unwinder's try() scope.
241
+ // { let _ = self.taskgroup.take(); }
242
+ self . death . collect_failure ( !self . unwinder . unwinding , self . taskgroup . take ( ) ) ;
248
243
self . destroyed = true ;
249
244
}
250
245
0 commit comments