about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-03-02 21:22:42 -0800
committerBrian Anderson <banderson@mozilla.com>2012-03-05 19:39:55 -0800
commitb2a075e20d07994c960a7598fee2771d10cb9989 (patch)
tree4e7a2fd278e8fb43ea692c15a89b7daac158adf5 /src
parentd7298a797b1041e9e997378bdb3cd4923567b2d4 (diff)
downloadrust-b2a075e20d07994c960a7598fee2771d10cb9989.tar.gz
rust-b2a075e20d07994c960a7598fee2771d10cb9989.zip
rt: Protect rust_task::state with a lock
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_task.cpp10
-rw-r--r--src/rt/rust_task.h6
-rw-r--r--src/rt/rust_task_thread.cpp4
3 files changed, 15 insertions, 5 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 92637ace632..dd0ae7846bc 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -74,7 +74,6 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state,
     cache(NULL),
     kernel(thread->kernel),
     name(name),
-    state(state),
     cond(NULL),
     cond_name("none"),
     list_index(-1),
@@ -87,6 +86,7 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state,
     dynastack(this),
     cc_counter(0),
     total_stack_sz(0),
+    state(state),
     killed(false),
     reentered_rust_stack(false),
     c_stack(NULL),
@@ -355,12 +355,14 @@ rust_task::get_frame_glue_fns(uintptr_t fp) {
 bool
 rust_task::running()
 {
+    scoped_lock with(state_lock);
     return state == &thread->running_tasks;
 }
 
 bool
 rust_task::blocked()
 {
+    scoped_lock with(state_lock);
     return state == &thread->blocked_tasks;
 }
 
@@ -373,6 +375,7 @@ rust_task::blocked_on(rust_cond *on)
 bool
 rust_task::dead()
 {
+    scoped_lock with(state_lock);
     return state == &thread->dead_tasks;
 }
 
@@ -407,7 +410,10 @@ rust_task::transition(rust_task_list *src, rust_task_list *dst) {
     I(thread, state == src);
     src->remove(this);
     dst->append(this);
-    state = dst;
+    {
+        scoped_lock with(state_lock);
+        state = dst;
+    }
     thread->lock.signal();
     if(unlock)
         thread->lock.unlock();
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 300c1df133c..cc4a2a0ffe3 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -68,7 +68,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
     // Fields known only to the runtime.
     rust_kernel *kernel;
     const char *const name;
-    rust_task_list *state;
     rust_cond *cond;
     const char *cond_name;
     int32_t list_index;
@@ -107,6 +106,9 @@ rust_task : public kernel_owned<rust_task>, rust_cond
 
 private:
 
+    lock_and_signal state_lock;
+    rust_task_list *state;
+
     // Protects the killed flag
     lock_and_signal kill_lock;
     // Indicates that the task was killed and needs to unwind
@@ -218,6 +220,8 @@ public:
     bool have_c_stack() { return c_stack != NULL; }
 
     rust_port_selector *get_port_selector() { return &port_selector; }
+
+    rust_task_list *get_state() { return state; }
 };
 
 // This stuff is on the stack-switching fast path
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp
index 20166e261b9..cb05a986476 100644
--- a/src/rt/rust_task_thread.cpp
+++ b/src/rt/rust_task_thread.cpp
@@ -259,7 +259,7 @@ rust_task_thread::start_main_loop() {
              ", state: %s",
              scheduled_task->name,
              (uintptr_t)scheduled_task,
-             scheduled_task->state->name);
+             scheduled_task->get_state()->name);
 
         place_task_in_tls(scheduled_task);
 
@@ -273,7 +273,7 @@ rust_task_thread::start_main_loop() {
              " in state '%s', worker id=%d" PRIxPTR,
              scheduled_task->name,
              (uintptr_t)scheduled_task,
-             scheduled_task->state->name,
+             scheduled_task->get_state()->name,
              id);
 
         reap_dead_tasks();