about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-06-18 13:49:20 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-06-20 20:12:14 -0700
commit1b642bf02f23d48c93047ae2fca9ebd7c2bdc518 (patch)
tree9a1a72ccadda56aacd62b6e146c158b2a1aeae32
parentb02172971fa658f2e6d3cdb3cbf3bf663801d656 (diff)
downloadrust-1b642bf02f23d48c93047ae2fca9ebd7c2bdc518.tar.gz
rust-1b642bf02f23d48c93047ae2fca9ebd7c2bdc518.zip
Change core::comm to use classes instead of resources
Ports now are represented internally as classes.
-rw-r--r--src/libcore/comm.rs51
1 files changed, 30 insertions, 21 deletions
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index 7c2a9737f04..7f43f6f308c 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -94,27 +94,31 @@ fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
     f(po.chan())
 }
 
-resource port_ptr<T: send>(po: *rust_port) unsafe {
+class port_ptr<T:send> {
+  let po: *rust_port;
+  new(po: *rust_port) { self.po = po; }
+  drop unsafe {
     task::unkillable {||
         // Once the port is detached it's guaranteed not to receive further
         // messages
         let yield = 0u;
         let yieldp = ptr::addr_of(yield);
-        rustrt::rust_port_begin_detach(po, yieldp);
+        rustrt::rust_port_begin_detach(self.po, yieldp);
         if yield != 0u {
             // Need to wait for the port to be detached
             // FIXME: If this fails then we're going to leave our port
             // in a bogus state. (Issue #1988)
             task::yield();
         }
-        rustrt::rust_port_end_detach(po);
+        rustrt::rust_port_end_detach(self.po);
 
         // Drain the port so that all the still-enqueued items get dropped
-        while rustrt::rust_port_size(po) > 0u as size_t {
-            recv_::<T>(po);
+        while rustrt::rust_port_size(self.po) > 0u as size_t {
+            recv_::<T>(self.po);
         }
-        rustrt::del_port(po);
+        rustrt::del_port(self.po);
     }
+  }
 }
 
 #[doc = "
@@ -126,21 +130,26 @@ Fails if the port is detached or dead. Fails if the port
 is owned by a different task.
 "]
 fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {
-    resource portref(p: *rust_port) {
-        if !ptr::is_null(p) {
-            rustrt::rust_port_drop(p);
-        }
+
+    class portref {
+       let p: *rust_port;
+       new(p: *rust_port) { self.p = p; }
+       drop {
+         if !ptr::is_null(self.p) {
+           rustrt::rust_port_drop(self.p);
+         }
+       }
     }
 
     let p = portref(rustrt::rust_port_take(*ch));
 
-    if ptr::is_null(*p) {
+    if ptr::is_null(p.p) {
         fail "unable to locate port for channel"
-    } else if rustrt::get_task_id() != rustrt::rust_port_task(*p) {
+    } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
         fail "unable to access unowned port"
     }
 
-    f(*p)
+    f(p.p)
 }
 
 #[doc = "
@@ -148,7 +157,7 @@ Constructs a channel. The channel is bound to the port used to
 construct it.
 "]
 fn chan<T: send>(p: port<T>) -> chan<T> {
-    chan_t(rustrt::get_port_id(***p))
+    chan_t(rustrt::get_port_id((**p).po))
 }
 
 #[doc = "
@@ -170,10 +179,10 @@ fn send<T: send>(ch: chan<T>, -data: T) {
 Receive from a port.  If no data is available on the port then the
 task will block until data becomes available.
 "]
-fn recv<T: send>(p: port<T>) -> T { recv_(***p) }
+fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }
 
 #[doc = "Returns true if there are messages available"]
-fn peek<T: send>(p: port<T>) -> bool { peek_(***p) }
+fn peek<T: send>(p: port<T>) -> bool { peek_((**p).po) }
 
 #[doc(hidden)]
 fn recv_chan<T: send>(ch: comm::chan<T>) -> T {
@@ -196,7 +205,7 @@ fn recv_<T: send>(p: *rust_port) -> T {
         // Data isn't available yet, so res has not been initialized.
         task::yield();
     } else {
-        // In the absense of compiler-generated preemption points
+        // In the absence of compiler-generated preemption points
         // this is a good place to yield
         task::yield();
     }
@@ -210,7 +219,7 @@ fn peek_(p: *rust_port) -> bool unsafe {
 #[doc = "Receive on one of two ports"]
 fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
     -> either<A, B> unsafe {
-    let ports = [***p_a, ***p_b];
+    let ports = [(**p_a).po, (**p_b).po];
     let n_ports = 2 as libc::size_t;
     let yield = 0u, yieldp = ptr::addr_of(yield);
 
@@ -233,9 +242,9 @@ fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
     // Now we know the port we're supposed to receive from
     assert resport != ptr::null();
 
-    if resport == ***p_a {
+    if resport == (**p_a).po {
         either::left(recv(p_a))
-    } else if resport == ***p_b {
+    } else if resport == (**p_b).po {
         either::right(recv(p_b))
     } else {
         fail "unexpected result from rust_port_select";
@@ -482,4 +491,4 @@ fn test_port_detach_fail() {
             }
         }
     }
-}
\ No newline at end of file
+}