diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2012-01-09 13:47:37 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-01-09 19:53:32 -0800 |
| commit | 110c3ccdcad4616fd558f248b61a4ba79d8ec86b (patch) | |
| tree | e211c5b764ed6899c2ecf55047ee1a15886b722e /src/rt | |
| parent | 005e3194858785e9debae8116caedf4c14e3b727 (diff) | |
add rust_task_is_unwinding predicate and do not kill if already unwinding
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_task.cpp | 27 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 6 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 1 |
3 files changed, 21 insertions, 13 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index edb356a9609..eb3040ebfae 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -245,7 +245,7 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state, running_on(-1), pinned_on(-1), local_region(&sched->srv->local_region), - failed(false), + unwinding(false), killed(false), propagate_failure(true), dynastack(this), @@ -299,27 +299,27 @@ struct spawn_args { struct cleanup_args { spawn_args *spargs; - bool failed; + bool threw_exception; }; void cleanup_task(cleanup_args *args) { spawn_args *a = args->spargs; - bool failed = args->failed; + bool threw_exception = args->threw_exception; rust_task *task = a->task; cc::do_cc(task); task->die(); - if (task->killed && !failed) { + if (task->killed && !threw_exception) { LOG(task, task, "Task killed during termination"); - failed = true; + threw_exception = true; } - task->notify(!failed); + task->notify(!threw_exception); - if (failed) { + if (threw_exception) { #ifndef __WIN32__ task->conclude_failure(); #else @@ -336,7 +336,7 @@ void task_start_wrapper(spawn_args *a) { rust_task *task = a->task; - bool failed = false; + bool threw_exception = false; try { // The first argument is the return pointer; as the task fn // must have void return type, we can safely pass 0. @@ -344,7 +344,7 @@ void task_start_wrapper(spawn_args *a) } catch (rust_task *ex) { A(task->sched, ex == task, "Expected this task to be thrown for unwinding"); - failed = true; + threw_exception = true; } rust_opaque_closure* env = a->envptr; @@ -357,7 +357,7 @@ void task_start_wrapper(spawn_args *a) } // The cleanup work needs lots of stack - cleanup_args ca = {a, failed}; + cleanup_args ca = {a, threw_exception}; task->sched->c_context.call_shim_on_c_stack(&ca, (void*)cleanup_task); task->ctx.next->swap(task->ctx); @@ -437,11 +437,17 @@ rust_task::kill() { // run_on_resume(rust_unwind_glue); } +extern "C" CDECL +bool rust_task_is_unwinding(rust_task *rt) { + return rt->unwinding; +} + void rust_task::fail() { // See note in ::kill() regarding who should call this. DLOG(sched, task, "task %s @0x%" PRIxPTR " failing", name, this); backtrace(); + unwinding = true; #ifndef __WIN32__ throw this; #else @@ -455,7 +461,6 @@ rust_task::fail() { void rust_task::conclude_failure() { fail_parent(); - failed = true; } void diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index d0e3d0e2ad6..b47b62e2d14 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -107,8 +107,10 @@ rust_task : public kernel_owned<rust_task>, rust_cond memory_region local_region; - // Indicates that the task ended in failure - bool failed; + // Indicates that fail() has been called and we are cleaning up. + // We use this to suppress the "killed" flag during calls to yield. + bool unwinding; + // Indicates that the task was killed and needs to unwind bool killed; bool propagate_failure; diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 86b41fcb256..8a44a7ab151 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -43,6 +43,7 @@ rust_ptr_eq rust_run_program rust_start rust_getcwd +rust_task_is_unwinding rust_task_sleep rust_get_task set_min_stack |
