diff --git a/src/lib/sys.rs b/src/lib/sys.rs index 0eafc5eec29..18e2d3261c7 100644 --- a/src/lib/sys.rs +++ b/src/lib/sys.rs @@ -17,5 +17,6 @@ fn align_of[T]() -> uint; fn refcount[T](@T t) -> uint; fn gc(); + fn unsupervise(); } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 091ba9c9a35..339452c5129 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -86,6 +86,11 @@ gc(rust_task *task) { task->gc(1); } +extern "C" CDECL void +unsupervise(rust_task *task) { + task->unsupervise(); +} + extern "C" CDECL rust_vec* vec_alloc(rust_task *task, type_desc *t, size_t n_elts) { diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index fafc1924a55..f877cefc71d 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -625,7 +625,7 @@ rust_task : public rc_base, ptr_vec *state; rust_cond *cond; uintptr_t* dptr; // Rendezvous pointer for send/recv. - rust_task *spawner; // Parent-link. + rust_task *supervisor; // Parent-link for failure propagation. size_t idx; size_t gc_alloc_thresh; size_t gc_alloc_accum; @@ -685,6 +685,9 @@ rust_task : public rc_base, // Run the gc glue on the task stack. void gc(size_t nargs); + // Disconnect from our supervisor. + void unsupervise(); + // Notify tasks waiting for us that we are about to die. void notify_waiting_tasks(); diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 5e230a589eb..09239c58fd8 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -62,7 +62,7 @@ rust_task::rust_task(rust_dom *dom, rust_task *spawner) : state(&dom->running_tasks), cond(NULL), dptr(0), - spawner(spawner), + supervisor(spawner), idx(0), waiting_tasks(dom), alarm(this) @@ -336,12 +336,12 @@ rust_task::fail(size_t nargs) { if (this == dom->root_task) dom->fail(); run_after_return(nargs, dom->root_crate->get_unwind_glue()); - if (spawner) { + if (supervisor) { dom->log(rust_log::TASK, "task 0x%" PRIxPTR - " propagating failure to parent 0x%" PRIxPTR, - this, spawner); - spawner->kill(); + " propagating failure to supervisor 0x%" PRIxPTR, + this, supervisor); + supervisor->kill(); } } @@ -353,6 +353,15 @@ rust_task::gc(size_t nargs) run_after_return(nargs, dom->root_crate->get_gc_glue()); } +void +rust_task::unsupervise() +{ + dom->log(rust_log::TASK, + "task 0x%" PRIxPTR " disconnecting from supervisor 0x%" PRIxPTR, + this, supervisor); + supervisor = NULL; +} + void rust_task::notify_waiting_tasks() {