about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-03-02 15:14:52 -0800
committerBrian Anderson <banderson@mozilla.com>2012-03-02 15:21:59 -0800
commit14306756b4a4f5f83043e3c2f91169a151fd54f5 (patch)
treef27078ef26a89eb22fc1fc6841689b20eb20a777 /src/rt
parent9ec94f714ab4d7175451095dc7438e6a9ee2cc0c (diff)
downloadrust-14306756b4a4f5f83043e3c2f91169a151fd54f5.tar.gz
rust-14306756b4a4f5f83043e3c2f91169a151fd54f5.zip
rt: Always delete task stacks on the task thread
There's not a real race here, but it makes helgrind happy and is arguably
less prone to future errrors.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_task.cpp17
-rw-r--r--src/rt/rust_task.h1
-rw-r--r--src/rt/rust_task_thread.cpp1
3 files changed, 12 insertions, 7 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index c6d1ce4f100..106190d76f8 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -121,13 +121,6 @@ rust_task::delete_this()
     I(thread, ref_count == 0); // ||
     //   (ref_count == 1 && this == sched->root_task));
 
-    // Delete all the stacks. There may be more than one if the task failed
-    // and no landing pads stopped to clean up.
-    // FIXME: We should do this when the task exits, not in the destructor
-    while (stk != NULL) {
-        del_stack();
-    }
-
     thread->release_task(this);
 }
 
@@ -726,6 +719,16 @@ rust_task::check_stack_canary() {
 }
 
 void
+rust_task::delete_all_stacks() {
+    I(thread, !on_rust_stack());
+    // Delete all the stacks. There may be more than one if the task failed
+    // and no landing pads stopped to clean up.
+    while (stk != NULL) {
+        del_stack();
+    }
+}
+
+void
 rust_task::config_notify(chan_handle chan) {
     notify_enabled = true;
     notify_chan = chan;
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index b1610f57582..7063c97f77b 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -205,6 +205,7 @@ public:
     void reset_stack_limit();
     bool on_rust_stack();
     void check_stack_canary();
+    void delete_all_stacks();
 
     void config_notify(chan_handle chan);
 
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp
index 39d9f283645..20166e261b9 100644
--- a/src/rt/rust_task_thread.cpp
+++ b/src/rt/rust_task_thread.cpp
@@ -144,6 +144,7 @@ rust_task_thread::reap_dead_tasks() {
         rust_task *task = dead_tasks_copy[i];
         // Release the task from the kernel so nobody else can get at it
         kernel->release_task_id(task->id);
+        task->delete_all_stacks();
         // Deref the task, which may cause it to request us to release it
         task->deref();
     }