diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-03-03 20:50:11 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-03-05 19:39:56 -0800 |
| commit | 0a5603cb58bdc66ad6b6a030e4e98ebeb3c13721 (patch) | |
| tree | 1092b7474081dfc2de16104edf9131e06a3b7329 /src/rt/rust_task_thread.cpp | |
| parent | cc276fe3c96965ba39b9fba3b588a1eaa3941d86 (diff) | |
| download | rust-0a5603cb58bdc66ad6b6a030e4e98ebeb3c13721.tar.gz rust-0a5603cb58bdc66ad6b6a030e4e98ebeb3c13721.zip | |
rt: Make linked failure less prone to deadlock
Still a mess.
Diffstat (limited to 'src/rt/rust_task_thread.cpp')
| -rw-r--r-- | src/rt/rust_task_thread.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp index cf16f209a4e..e108a21f3a9 100644 --- a/src/rt/rust_task_thread.cpp +++ b/src/rt/rust_task_thread.cpp @@ -2,6 +2,7 @@ #include <stdarg.h> #include <cassert> #include <pthread.h> +#include <vector> #include "rust_internal.h" #include "rust_util.h" #include "globals.h" @@ -95,19 +96,27 @@ rust_task_thread::fail() { void rust_task_thread::kill_all_tasks() { - I(this, !lock.lock_held_by_current_thread()); - scoped_lock with(lock); + std::vector<rust_task*> all_tasks; - for (size_t i = 0; i < running_tasks.length(); i++) { - // We don't want the failure of these tasks to propagate back - // to the kernel again since we're already failing everything - running_tasks[i]->unsupervise(); - running_tasks[i]->kill(); + { + scoped_lock with(lock); + + for (size_t i = 0; i < running_tasks.length(); i++) { + all_tasks.push_back(running_tasks[i]); + } + + for (size_t i = 0; i < blocked_tasks.length(); i++) { + all_tasks.push_back(blocked_tasks[i]); + } } - for (size_t i = 0; i < blocked_tasks.length(); i++) { - blocked_tasks[i]->unsupervise(); - blocked_tasks[i]->kill(); + while (!all_tasks.empty()) { + rust_task *task = all_tasks.back(); + all_tasks.pop_back(); + // We don't want the failure of these tasks to propagate back + // to the kernel again since we're already failing everything + task->unsupervise(); + task->kill(); } } |
