about summary refs log tree commit diff
path: root/src/rt/rust_task_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_task_thread.cpp')
-rw-r--r--src/rt/rust_task_thread.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp
index 6251d5c24c1..236eaaab98e 100644
--- a/src/rt/rust_task_thread.cpp
+++ b/src/rt/rust_task_thread.cpp
@@ -136,16 +136,30 @@ rust_task_thread::reap_dead_tasks() {
 
     for (size_t i = 0; i < dead_tasks_len; ++i) {
         rust_task *task = dead_tasks_copy[i];
-        if (task) {
-            kernel->release_task_id(task->user.id);
-            task->deref();
-        }
+        // Release the task from the kernel so nobody else can get at it
+        kernel->release_task_id(task->user.id);
+        // Deref the task, which may cause it to request us to release it
+        task->deref();
     }
     srv->free(dead_tasks_copy);
 
     lock.lock();
 }
 
+void
+rust_task_thread::release_task(rust_task *task) {
+    // Nobody should have a ref to the task at this point
+    I(this, task->ref_count == 0);
+    // Kernel should not know about the task any more
+    I(this, kernel->get_task_by_id(task->user.id) == NULL);
+    // Now delete the task, which will require using this thread's
+    // memory region.
+    delete task;
+    // Now release the task from the scheduler, which may trigger this
+    // thread to exit
+    sched->release_task();
+}
+
 /**
  * Schedules a running task for execution. Only running tasks can be
  * activated.  Blocked tasks have to be unblocked before they can be