about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-07-12 19:44:05 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-07-12 19:49:49 -0400
commitacb86921a62ba01726fd922f55d0176fa6c1df7c (patch)
tree765f505df7a21bf922f1ac84bb9c3c5596a29211 /src/rt/rust_task.cpp
parent08c40c5eb7bda79850f725308b72c1451fb67a86 (diff)
downloadrust-acb86921a62ba01726fd922f55d0176fa6c1df7c.tar.gz
rust-acb86921a62ba01726fd922f55d0176fa6c1df7c.zip
Revert linked failure
This reverts commit 5d6d3d056592cf4d68afbce6084245ea6733865c.
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index d23d74b0ea2..f5e2fcc9a08 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -10,8 +10,6 @@
 #include "rust_env.h"
 #include "rust_port.h"
 
-// TODO(bblum): get rid of supervisors
-
 // Tasks
 rust_task::rust_task(rust_sched_loop *sched_loop, rust_task_state state,
                      rust_task *spawner, const char *name,
@@ -148,9 +146,13 @@ cleanup_task(cleanup_args *args) {
 
     task->notify(!threw_exception);
 
-#ifdef __WIN32__
-    assert(!threw_exception && "No exception-handling yet on windows builds");
+    if (threw_exception) {
+#ifndef __WIN32__
+        task->conclude_failure();
+#else
+        assert(false && "Shouldn't happen");
 #endif
+    }
 }
 
 extern "C" CDECL void upcall_exchange_free(void *ptr);
@@ -260,7 +262,10 @@ void
 rust_task::kill() {
     scoped_lock with(kill_lock);
 
-    // XXX: bblum: kill/kill race
+    if (dead()) {
+        // Task is already dead, can't kill what's already dead.
+        fail_parent();
+    }
 
     // Note the distinction here: kill() is when you're in an upcall
     // from task A and want to force-fail task B, you do B->kill().
@@ -309,12 +314,32 @@ rust_task::begin_failure(char const *expr, char const *file, size_t line) {
     throw this;
 #else
     die();
+    conclude_failure();
     // FIXME (#908): Need unwinding on windows. This will end up aborting
     sched_loop->fail();
 #endif
 }
 
 void
+rust_task::conclude_failure() {
+    fail_parent();
+}
+
+void
+rust_task::fail_parent() {
+    scoped_lock with(supervisor_lock);
+    if (supervisor) {
+        DLOG(sched_loop, task,
+             "task %s @0x%" PRIxPTR
+             " propagating failure to supervisor %s @0x%" PRIxPTR,
+             name, this, supervisor->name, supervisor);
+        supervisor->kill();
+    }
+    if (NULL == supervisor && propagate_failure)
+        sched_loop->fail();
+}
+
+void
 rust_task::unsupervise()
 {
     scoped_lock with(supervisor_lock);