about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-08-01 14:57:17 -0700
committerEric Holk <eholk@mozilla.com>2011-08-01 15:58:39 -0700
commit939bca0d84af1b52539d7b02a3be03bd64fcc17d (patch)
tree86e2bc7184d92002ad9dcb7c214af595be21a559 /src
parent6a6d5c669e363238abbed050f62658ee6e74cbbf (diff)
downloadrust-939bca0d84af1b52539d7b02a3be03bd64fcc17d.tar.gz
rust-939bca0d84af1b52539d7b02a3be03bd64fcc17d.zip
Added send and receive to comm library.
Diffstat (limited to 'src')
-rw-r--r--src/lib/comm.rs11
-rw-r--r--src/rt/rust_builtin.cpp30
-rw-r--r--src/rt/rust_upcall.cpp24
-rw-r--r--src/rt/rustrt.def.in2
-rw-r--r--src/test/stdtest/comm.rs12
5 files changed, 56 insertions, 23 deletions
diff --git a/src/lib/comm.rs b/src/lib/comm.rs
index ad86e2a7a5f..1665626432a 100644
--- a/src/lib/comm.rs
+++ b/src/lib/comm.rs
@@ -1,4 +1,6 @@
 import sys;
+import ptr;
+import unsafe;
 
 export _chan;
 export _port;
@@ -6,16 +8,19 @@ export _port;
 export mk_port;
 
 native "rust" mod rustrt {
+    type void;
     type rust_chan;
     type rust_port;
 
     fn new_chan(po : *rust_port) -> *rust_chan;
     fn del_chan(ch : *rust_chan);
     fn drop_chan(ch : *rust_chan);
+    fn chan_send(ch: *rust_chan, v : *void);
 
     fn new_port(unit_sz : uint) -> *rust_port;
     fn del_port(po : *rust_port);
     fn drop_port(po : *rust_port);
+    fn port_recv(dp : *void, po : *rust_port);
 }
 
 resource chan_ptr(ch: *rustrt::rust_chan) {
@@ -32,7 +37,8 @@ resource port_ptr(po: *rustrt::rust_port) {
 
 obj _chan[T](raw_chan : @chan_ptr) {
     fn send(v : &T) {
-
+        rustrt::chan_send(**raw_chan,
+                          unsafe::reinterpret_cast(ptr::addr_of(v)));
     }
 }
 
@@ -42,7 +48,8 @@ obj _port[T](raw_port : @port_ptr) {
     }
 
     fn recv_into(v : &T) {
-
+        rustrt::port_recv(unsafe::reinterpret_cast(ptr::addr_of(v)),
+                          **raw_port);
     }
 }
 
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 989e0a4800a..99eb61aff36 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -914,6 +914,36 @@ void drop_port(rust_task *, rust_port *port) {
     port->ref_count--;
 }
 
+extern "C" CDECL void
+chan_send(rust_task *task, rust_chan *chan, void *sptr) {
+    chan->send(sptr);
+}
+
+extern "C" CDECL void
+port_recv(rust_task *task, uintptr_t *dptr, rust_port *port) {
+    {
+        scoped_lock with(port->lock);
+
+        LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR
+            ", size: 0x%" PRIxPTR ", chan_no: %d",
+            (uintptr_t) port, (uintptr_t) dptr, port->unit_sz,
+            port->chans.length());
+
+        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");
+    }
+    task->yield(3);
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index c8d71165a8a..4946a516479 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -194,29 +194,11 @@ upcall_send(rust_task *task, rust_chan *chan, void *sptr) {
 }
 
 extern "C" CDECL void
+port_recv(rust_task *task, uintptr_t *dptr, rust_port *port);
+extern "C" CDECL void
 upcall_recv(rust_task *task, uintptr_t *dptr, rust_port *port) {
     LOG_UPCALL_ENTRY(task);
-    {
-        scoped_lock with(port->lock);
-
-        LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR
-            ", size: 0x%" PRIxPTR ", chan_no: %d",
-            (uintptr_t) port, (uintptr_t) dptr, port->unit_sz,
-            port->chans.length());
-
-        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");
-    }
-    task->yield(3);
+    port_recv(task, dptr, port);
 }
 
 extern "C" CDECL void
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 49e2cbc9c1e..e818b9ac83d 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -1,4 +1,5 @@
 align_of
+chan_send
 check_claims
 clone_chan
 debug_box
@@ -27,6 +28,7 @@ nano_time
 new_chan
 new_port
 pin_task
+port_recv
 unpin_task
 rand_free
 rand_new
diff --git a/src/test/stdtest/comm.rs b/src/test/stdtest/comm.rs
index 27568f53c79..706cca7ddaf 100644
--- a/src/test/stdtest/comm.rs
+++ b/src/test/stdtest/comm.rs
@@ -6,3 +6,15 @@ fn create_port_and_chan() {
     let p = comm::mk_port[int]();
     let c = p.mk_chan();
 }
+
+#[test]
+fn send_recv() {
+    let p = comm::mk_port();
+    let c = p.mk_chan();
+
+    c.send(42);
+    let v = 0;
+    p.recv_into(v);
+
+    assert(42 == v);
+}