about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_builtin.cpp24
-rw-r--r--src/rt/rust_port.cpp26
-rw-r--r--src/rt/rust_port.h2
3 files changed, 24 insertions, 28 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index d37245c29a4..b6ad9397e9c 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -544,29 +544,7 @@ rust_task_yield(rust_task *task, bool *killed) {
 
 extern "C" CDECL void
 port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
-    *yield = false;
-    rust_task *task = rust_task_thread::get_task();
-    {
-        scoped_lock with(port->lock);
-
-        LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR
-            ", size: 0x%" PRIxPTR,
-            (uintptr_t) port, (uintptr_t) dptr, port->unit_sz);
-
-        if (port->receive(dptr)) {
-            return;
-        }
-
-        // No data was buffered on any incoming channel, so block this task on
-        // the port. Remember the rendezvous location so that any sender task
-        // can write to it before waking up this task.
-
-        LOG(task, comm, "<=== waiting for rendezvous data ===");
-        task->rendezvous_ptr = dptr;
-        task->block(port, "waiting for rendezvous data");
-    }
-    *yield = true;
-    return;
+    port->receive(dptr, yield);
 }
 
 extern "C" CDECL void
diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp
index f4843971e42..41884f8f60c 100644
--- a/src/rt/rust_port.cpp
+++ b/src/rt/rust_port.cpp
@@ -63,14 +63,32 @@ void rust_port::send(void *sptr) {
     }
 }
 
-bool rust_port::receive(void *dptr) {
-    I(task->thread, lock.lock_held_by_current_thread());
+void rust_port::receive(void *dptr, uintptr_t *yield) {
+    I(task->thread, !lock.lock_held_by_current_thread());
+
+    LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR
+        ", size: 0x%" PRIxPTR,
+        (uintptr_t) this, (uintptr_t) dptr, unit_sz);
+
+    scoped_lock with(lock);
+
+    *yield = false;
+
     if (buffer.is_empty() == false) {
         buffer.dequeue(dptr);
         LOG(task, comm, "<=== read data ===");
-        return true;
+        return;
     }
-    return false;
+
+    // No data was buffered on any incoming channel, so block this task on
+    // the port. Remember the rendezvous location so that any sender task
+    // can write to it before waking up this task.
+
+    LOG(task, comm, "<=== waiting for rendezvous data ===");
+    task->rendezvous_ptr = (uintptr_t*) dptr;
+    task->block(this, "waiting for rendezvous data");
+
+    *yield = true;
 }
 
 size_t rust_port::size() {
diff --git a/src/rt/rust_port.h b/src/rt/rust_port.h
index 92ece8a7841..0fbfeeac2ec 100644
--- a/src/rt/rust_port.h
+++ b/src/rt/rust_port.h
@@ -20,7 +20,7 @@ public:
     ~rust_port();
     void log_state();
     void send(void *sptr);
-    bool receive(void *dptr);
+    void receive(void *dptr, uintptr_t *yield);
     size_t size();
     void detach();
 };