about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/rt/rust_kernel.cpp5
-rw-r--r--src/rt/rust_kernel.h1
-rw-r--r--src/rt/rust_scheduler.cpp5
3 files changed, 6 insertions, 5 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp
index 004e42a8138..8f41182d791 100644
--- a/src/rt/rust_kernel.cpp
+++ b/src/rt/rust_kernel.cpp
@@ -21,10 +21,6 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
     live_schedulers = 1;
 }
 
-rust_kernel::~rust_kernel() {
-    delete sched;
-}
-
 void
 rust_kernel::log(uint32_t level, char const *fmt, ...) {
     char buf[BUF_BYTES];
@@ -83,6 +79,7 @@ void
 rust_kernel::release_scheduler() {
     I(this, !sched_lock.lock_held_by_current_thread());
     scoped_lock with(sched_lock);
+    delete sched;
     --live_schedulers;
     if (live_schedulers == 0) {
         // We're all done. Tell the main thread to continue
diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h
index 9a59a35e908..fdf9f5eb0f7 100644
--- a/src/rt/rust_kernel.h
+++ b/src/rt/rust_kernel.h
@@ -47,7 +47,6 @@ public:
     struct rust_env *env;
 
     rust_kernel(rust_srv *srv, size_t num_threads);
-    ~rust_kernel();
 
     void log(uint32_t level, char const *fmt, ...);
     void fatal(char const *fmt, ...);
diff --git a/src/rt/rust_scheduler.cpp b/src/rt/rust_scheduler.cpp
index 904eb5cafcb..666733a4318 100644
--- a/src/rt/rust_scheduler.cpp
+++ b/src/rt/rust_scheduler.cpp
@@ -56,6 +56,11 @@ rust_scheduler::destroy_task_threads() {
 void
 rust_scheduler::start_task_threads()
 {
+    // Copy num_threads because it's possible for the last thread
+    // to terminate and have the kernel delete us before we
+    // hit the last check against num_threads, in which case
+    // we would be accessing invalid memory.
+    uintptr_t num_threads = this->num_threads;
     for(size_t i = 0; i < num_threads; ++i) {
         rust_task_thread *thread = threads[i];
         thread->start();