about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_builtin.cpp4
-rw-r--r--src/rt/rust_task.cpp35
-rw-r--r--src/rt/rust_task.h2
3 files changed, 18 insertions, 23 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 30b915f4e96..e8109ea7a04 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -471,6 +471,7 @@ extern "C" CDECL void
 del_port(rust_port *port) {
     rust_task *task = rust_scheduler::get_task();
     LOG(task, comm, "del_port(0x%" PRIxPTR ")", (uintptr_t) port);
+    scoped_lock with(task->lock);
     port->deref();
 }
 
@@ -487,11 +488,12 @@ chan_id_send(type_desc *t, rust_task_id target_task_id,
     rust_task *target_task = task->kernel->get_task_by_id(target_task_id);
     if(target_task) {
         rust_port *port = target_task->get_port_by_id(target_port_id);
-        target_task->deref();
         if(port) {
             port->send(sptr);
+            scoped_lock with(target_task->lock);
             port->deref();
         }
+        target_task->deref();
     }
 }
 
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 5164f6ac181..e5d43e7b308 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -127,15 +127,20 @@ rust_task::~rust_task()
          name, (uintptr_t)this, ref_count);
 
     if(user.notify_enabled) {
-        rust_port *target =
-            get_port_by_chan_handle(&user.notify_chan);
-        if(target) {
-            task_notification msg;
-            msg.id = user.id;
-            msg.result = failed ? tr_failure : tr_success;
-
-            target->send(&msg);
-            target->deref();
+        rust_task *target_task = kernel->get_task_by_id(user.notify_chan.task);
+        if (target_task) {
+            rust_port *target_port =
+                target_task->get_port_by_id(user.notify_chan.port);
+            if(target_port) {
+                task_notification msg;
+                msg.id = user.id;
+                msg.result = failed ? tr_failure : tr_success;
+
+                target_port->send(&msg);
+                scoped_lock with(target_task->lock);
+                target_port->deref();
+            }
+            target_task->deref();
         }
     }
 
@@ -553,8 +558,7 @@ rust_port_id rust_task::register_port(rust_port *port) {
 }
 
 void rust_task::release_port(rust_port_id id) {
-    I(sched, !lock.lock_held_by_current_thread());
-    scoped_lock with(lock);
+    I(sched, lock.lock_held_by_current_thread());
     port_table.remove(id);
 }
 
@@ -569,15 +573,6 @@ rust_port *rust_task::get_port_by_id(rust_port_id id) {
     return port;
 }
 
-rust_port *rust_task::get_port_by_chan_handle(chan_handle *handle) {
-    rust_task *target_task = kernel->get_task_by_id(handle->task);
-    if(target_task) {
-        rust_port *port = target_task->get_port_by_id(handle->port);
-        target_task->deref();
-        return port;
-    }
-    return NULL;
-}
 
 // Temporary routine to allow boxes on one task's shared heap to be reparented
 // to another.
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 3bdc900250d..2d8afa619cd 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -209,8 +209,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
     // not at all safe.
     intptr_t get_ref_count() const { return ref_count; }
 
-    rust_port *get_port_by_chan_handle(chan_handle *handle);
-
     // FIXME: These functions only exist to get the tasking system off the
     // ground. We should never be migrating shared boxes between tasks.
     const type_desc *release_alloc(void *alloc);