From 04d9cc18a569f5d8a8b7c2c07a42259af41d7cb3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 2 Mar 2012 16:33:24 -0800 Subject: [PATCH] rt: Protect rust_task::supervisor with a lock --- src/rt/rust_task.cpp | 14 ++++++++++---- src/rt/rust_task.h | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 106190d76f8..756dc0fbc4d 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -77,7 +77,6 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state, state(state), cond(NULL), cond_name("none"), - supervisor(spawner), list_index(-1), next_port_id(0), rendezvous_ptr(0), @@ -92,7 +91,8 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state, reentered_rust_stack(false), c_stack(NULL), next_c_sp(0), - next_rust_sp(0) + next_rust_sp(0), + supervisor(spawner) { LOGPTR(thread, "new task", (uintptr_t)this); DLOG(thread, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this); @@ -103,6 +103,7 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state, } } +// NB: This does not always run on the task's scheduler thread void rust_task::delete_this() { @@ -112,8 +113,11 @@ rust_task::delete_this() name, (uintptr_t)this, ref_count); // FIXME: We should do this when the task exits, not in the destructor - if (supervisor) { - supervisor->deref(); + { + scoped_lock with(supervisor_lock); + if (supervisor) { + supervisor->deref(); + } } /* FIXME: tighten this up, there are some more @@ -302,6 +306,7 @@ rust_task::conclude_failure() { void rust_task::fail_parent() { + scoped_lock with(supervisor_lock); if (supervisor) { DLOG(thread, task, "task %s @0x%" PRIxPTR @@ -317,6 +322,7 @@ rust_task::fail_parent() { void rust_task::unsupervise() { + scoped_lock with(supervisor_lock); if (supervisor) { DLOG(thread, task, "task %s @0x%" PRIxPTR diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 7063c97f77b..28446d9048a 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -71,7 +71,6 @@ rust_task : public kernel_owned, rust_cond rust_task_list *state; rust_cond *cond; const char *cond_name; - rust_task *supervisor; // Parent-link for failure propagation. int32_t list_index; rust_port_id next_port_id; @@ -120,6 +119,9 @@ private: rust_port_selector port_selector; + lock_and_signal supervisor_lock; + rust_task *supervisor; // Parent-link for failure propagation. + // Called when the atomic refcount reaches zero void delete_this();