@@ -27,6 +27,7 @@ use super::local_heap::LocalHeap;
2727use rt:: sched:: { Scheduler , SchedHandle } ;
2828use rt:: stack:: { StackSegment , StackPool } ;
2929use rt:: context:: Context ;
30+ use unstable:: finally:: Finally ;
3031use task:: spawn:: Taskgroup ;
3132use cell:: Cell ;
3233
@@ -211,40 +212,34 @@ impl Task {
211212
212213 pub fn run ( & mut self , f : & fn ( ) ) {
213214 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- }
224215
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 {
231219
232- rtdebug ! ( "DESTROYING TASK: %u" , borrow:: to_uint( self ) ) ;
220+ // Run the task main function, then do some cleanup.
221+ do f. finally {
233222
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+ }
237230
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 ( ) ; }
241233 }
242- _ => ( )
243234 }
244235
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 ( ) ) ;
248243 self . destroyed = true ;
249244 }
250245
0 commit comments