diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-03-02 01:39:19 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-03-05 19:39:56 -0800 |
| commit | f057f003009fc84e2e80b3df7673eb9cae7f4810 (patch) | |
| tree | d05cdc784337deaa73dad9232b75d72c256a98b5 /src/rt/rust_task_thread.cpp | |
| parent | 8efe4b89137646c5315677b029d4158424c126cc (diff) | |
| download | rust-f057f003009fc84e2e80b3df7673eb9cae7f4810.tar.gz rust-f057f003009fc84e2e80b3df7673eb9cae7f4810.zip | |
rt: Simplify reap_dead_tasks
Diffstat (limited to 'src/rt/rust_task_thread.cpp')
| -rw-r--r-- | src/rt/rust_task_thread.cpp | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp index 5e396badd62..eafeac305be 100644 --- a/src/rt/rust_task_thread.cpp +++ b/src/rt/rust_task_thread.cpp @@ -122,33 +122,26 @@ rust_task_thread::number_of_live_tasks() { void rust_task_thread::reap_dead_tasks() { I(this, lock.lock_held_by_current_thread()); + if (dead_tasks.length() == 0) { return; } + A(this, dead_tasks.length() == 1, + "Only one task should die during a single turn of the event loop"); + // First make a copy of the dead_task list with the lock held - size_t dead_tasks_len = dead_tasks.length(); - rust_task **dead_tasks_copy = (rust_task**) - srv->malloc(sizeof(rust_task*) * dead_tasks_len); - for (size_t i = 0; i < dead_tasks_len; ++i) { - dead_tasks_copy[i] = dead_tasks.pop_value(); - } + rust_task *dead_task = dead_tasks.pop_value(); - // Now unlock again because we have to actually free the dead tasks, - // and that may end up wanting to lock the kernel lock. We have - // a kernel lock -> scheduler lock locking order that we need - // to maintain. + // Dereferencing the task will probably cause it to be released + // from the scheduler, which may end up trying to take this lock lock.unlock(); - for (size_t i = 0; i < dead_tasks_len; ++i) { - rust_task *task = dead_tasks_copy[i]; - // Release the task from the kernel so nobody else can get at it - kernel->release_task_id(task->id); - task->delete_all_stacks(); - // Deref the task, which may cause it to request us to release it - task->deref(); - } - srv->free(dead_tasks_copy); + // Release the task from the kernel so nobody else can get at it + kernel->release_task_id(dead_task->id); + dead_task->delete_all_stacks(); + // Deref the task, which may cause it to request us to release it + dead_task->deref(); lock.lock(); } |
