about summary refs log tree commit diff
path: root/src/rt/rust_chan.cpp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-29 11:00:44 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-07-29 18:54:59 -0700
commitd1dbb99984064eedb77c0f55300430bcb35ce109 (patch)
tree9e45ab1c525f0c59ac892117d0dd5424d29a7f51 /src/rt/rust_chan.cpp
parentbc4e9afe2547fa88b55ffc31fef041dffe864b2b (diff)
downloadrust-d1dbb99984064eedb77c0f55300430bcb35ce109.tar.gz
rust-d1dbb99984064eedb77c0f55300430bcb35ce109.zip
Removing proxies and message queues.
Diffstat (limited to 'src/rt/rust_chan.cpp')
-rw-r--r--src/rt/rust_chan.cpp107
1 files changed, 39 insertions, 68 deletions
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp
index 9017e9a2bc1..3ade237c25a 100644
--- a/src/rt/rust_chan.cpp
+++ b/src/rt/rust_chan.cpp
@@ -4,7 +4,7 @@
 /**
  * Create a new rust channel and associate it with the specified port.
  */
-rust_chan::rust_chan(rust_kernel *kernel, maybe_proxy<rust_port> *port,
+rust_chan::rust_chan(rust_kernel *kernel, rust_port *port,
                      size_t unit_sz)
     : ref_count(1),
       kernel(kernel),
@@ -29,18 +29,16 @@ rust_chan::~rust_chan() {
 /**
  * Link this channel with the specified port.
  */
-void rust_chan::associate(maybe_proxy<rust_port> *port) {
+void rust_chan::associate(rust_port *port) {
     this->port = port;
-    if (port->is_proxy() == false) {
-        scoped_lock with(port->referent()->lock);
-        KLOG(kernel, task,
-            "associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
-            this, port);
-        ++this->ref_count;
-        this->task = port->referent()->task;
-        this->task->ref();
-        this->port->referent()->chans.push(this);
-    }
+    scoped_lock with(port->lock);
+    KLOG(kernel, task,
+         "associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
+         this, port);
+    ++this->ref_count;
+    this->task = port->task;
+    this->task->ref();
+    this->port->chans.push(this);
 }
 
 bool rust_chan::is_associated() {
@@ -52,19 +50,17 @@ bool rust_chan::is_associated() {
  */
 void rust_chan::disassociate() {
     A(kernel,
-      port->referent()->lock.lock_held_by_current_thread(),
+      port->lock.lock_held_by_current_thread(),
       "Port referent lock must be held to call rust_chan::disassociate");
     A(kernel, is_associated(),
       "Channel must be associated with a port.");
-    if (port->is_proxy() == false) {
-        KLOG(kernel, task,
-             "disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
-             this, port->referent());
-        --this->ref_count;
-        task->deref();
-        this->task = NULL;
-        port->referent()->chans.swap_delete(this);
-    }
+    KLOG(kernel, task,
+         "disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
+         this, port);
+    --this->ref_count;
+    task->deref();
+    this->task = NULL;
+    port->chans.swap_delete(this);
 
     // Delete reference to the port.
     port = NULL;
@@ -74,12 +70,7 @@ void rust_chan::disassociate() {
  * Attempt to send data to the associated port.
  */
 void rust_chan::send(void *sptr) {
-    I(kernel, !port->is_proxy());
-
-    rust_port *target_port = port->referent();
-    // TODO: We can probably avoid this lock by using atomic operations in
-    // circular_buffer.
-    scoped_lock with(target_port->lock);
+    scoped_lock with(port->lock);
 
     buffer.enqueue(sptr);
 
@@ -92,28 +83,17 @@ void rust_chan::send(void *sptr) {
     A(kernel, !buffer.is_empty(),
       "rust_chan::transmit with nothing to send.");
 
-    if (port->is_proxy()) {
-        data_message::send(buffer.peek(), buffer.unit_sz, "send data",
-                           task->get_handle(), port->as_proxy()->handle());
-        buffer.dequeue(NULL);
-    } else {
-        if (target_port->task->blocked_on(target_port)) {
-            KLOG(kernel, comm, "dequeued in rendezvous_ptr");
-            buffer.dequeue(target_port->task->rendezvous_ptr);
-            target_port->task->rendezvous_ptr = 0;
-            target_port->task->wakeup(target_port);
-            return;
-        }
+    if (port->task->blocked_on(port)) {
+        KLOG(kernel, comm, "dequeued in rendezvous_ptr");
+        buffer.dequeue(port->task->rendezvous_ptr);
+        port->task->rendezvous_ptr = 0;
+        port->task->wakeup(port);
     }
-
-    return;
 }
 
 rust_chan *rust_chan::clone(rust_task *target) {
-    size_t unit_sz = buffer.unit_sz;
-    maybe_proxy<rust_port> *port = this->port;
     return new (target->kernel, "cloned chan")
-        rust_chan(kernel, port, unit_sz);
+        rust_chan(kernel, port, buffer.unit_sz);
 }
 
 /**
@@ -125,30 +105,21 @@ void rust_chan::destroy() {
       "Channel's ref count should be zero.");
 
     if (is_associated()) {
-        if (port->is_proxy()) {
-            // Here is a good place to delete the port proxy we allocated
-            // in upcall_clone_chan.
-            rust_proxy<rust_port> *proxy = port->as_proxy();
-            scoped_lock with(port->referent()->lock);
-            disassociate();
-            delete proxy;
-        } else {
-            // We're trying to delete a channel that another task may be
-            // reading from. We have two options:
-            //
-            // 1. We can flush the channel by blocking in upcall_flush_chan()
-            //    and resuming only when the channel is flushed. The problem
-            //    here is that we can get ourselves in a deadlock if the
-            //    parent task tries to join us.
-            //
-            // 2. We can leave the channel in a "dormnat" state by not freeing
-            //    it and letting the receiver task delete it for us instead.
-            if (buffer.is_empty() == false) {
-                return;
-            }
-            scoped_lock with(port->referent()->lock);
-            disassociate();
+        // We're trying to delete a channel that another task may be
+        // reading from. We have two options:
+        //
+        // 1. We can flush the channel by blocking in upcall_flush_chan()
+        //    and resuming only when the channel is flushed. The problem
+        //    here is that we can get ourselves in a deadlock if the
+        //    parent task tries to join us.
+        //
+        // 2. We can leave the channel in a "dormnat" state by not freeing
+        //    it and letting the receiver task delete it for us instead.
+        if (buffer.is_empty() == false) {
+            return;
         }
+        scoped_lock with(port->lock);
+        disassociate();
     }
     delete this;
 }