diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-12 02:42:56 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-12 18:08:36 -0400 |
| commit | 200a2ded3245eb0a1ca7b265ce83adba16d75b97 (patch) | |
| tree | 9874f527ab85ef32d2d9dc813685a1add5a03a51 /src/rt | |
| parent | 343e9de8ef4ee9727f027c896ce99f09611b9603 (diff) | |
| download | rust-200a2ded3245eb0a1ca7b265ce83adba16d75b97.tar.gz rust-200a2ded3245eb0a1ca7b265ce83adba16d75b97.zip | |
Fix linked failure with root taskgroup to kill the runtime too.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 5 | ||||
| -rw-r--r-- | src/rt/rust_sched_loop.cpp | 4 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 12 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 4 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 1 |
5 files changed, 23 insertions, 3 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 55f1f8bf17e..f648ed8d78c 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -863,6 +863,11 @@ rust_task_kill_other(rust_task *task) { /* Used for linked failure */ task->kill(); } +extern "C" void +rust_task_kill_all(rust_task *task) { + task->fail_sched_loop(); +} + extern "C" rust_cond_lock* rust_create_cond_lock() { return new rust_cond_lock(); diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index 4aed9a5e061..54ebccfe8c3 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/src/rt/rust_sched_loop.cpp @@ -260,8 +260,8 @@ rust_task * rust_sched_loop::create_task(rust_task *spawner, const char *name) { rust_task *task = new (this->kernel, "rust_task") - rust_task (this, task_state_newborn, - spawner, name, kernel->env->min_stack_size); + rust_task(this, task_state_newborn, + spawner, name, kernel->env->min_stack_size); DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s", task, spawner ? spawner->name : "null", name); diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 3d88c05b3ff..a6c9b791fda 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -129,6 +129,11 @@ cleanup_task(cleanup_args *args) { // assert(task->task_local_data != NULL); task->task_local_data_cleanup(task->task_local_data); task->task_local_data = NULL; + } else if (threw_exception) { + // Edge case: If main never spawns any tasks, but fails anyway, TLS + // won't be around to take down the kernel (task.rs:kill_taskgroup, + // rust_task_kill_all). Do it here instead. + task->fail_sched_loop(); } // FIXME (#2676): For performance we should do the annihilator @@ -282,6 +287,7 @@ rust_task::kill() { LOG(this, task, "preparing to unwind task: 0x%" PRIxPTR, this); } +// TODO(bblum): Move this to rust_builtin.cpp (cleanup) extern "C" CDECL bool rust_task_is_unwinding(rust_task *rt) { return rt->unwinding; @@ -315,10 +321,14 @@ rust_task::begin_failure(char const *expr, char const *file, size_t line) { #else die(); // FIXME (#908): Need unwinding on windows. This will end up aborting - sched_loop->fail(); + fail_sched_loop(); #endif } +void rust_task::fail_sched_loop() { + sched_loop->fail(); +} + void rust_task::unsupervise() { diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 1d87a0ed56c..d562d151894 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -275,6 +275,10 @@ public: void fail(); void fail(char const *expr, char const *file, size_t line); + // Propagate failure to the entire rust runtime. + // TODO(bblum): maybe this can be done at rust-level? + void fail_sched_loop(); + // Disconnect from our supervisor. void unsupervise(); diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 300d6bc79e8..a8256bba300 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -178,6 +178,7 @@ rust_port_task rust_task_inhibit_kill rust_task_allow_kill rust_task_kill_other +rust_task_kill_all rust_create_cond_lock rust_destroy_cond_lock rust_lock_cond_lock |
