Skip to content

Commit 93432a2

Browse files
committed
auto merge of #8269 : brson/rust/fix-task-cleanup, r=brson
...y/catch And before collect_failure. These are both running user dtors and need to be handled in the task try/catch block and before the final task cleanup code.
2 parents 8ce9533 + 3c9e393 commit 93432a2

File tree

1 file changed

+22
-27
lines changed

1 file changed

+22
-27
lines changed

src/libstd/rt/task.rs

+22-27
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use super::local_heap::LocalHeap;
2727
use rt::sched::{Scheduler, SchedHandle};
2828
use rt::stack::{StackSegment, StackPool};
2929
use rt::context::Context;
30+
use unstable::finally::Finally;
3031
use task::spawn::Taskgroup;
3132
use 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

Comments
 (0)