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-08-06 10:07:39 -0700
committerEric Holk <eholk@mozilla.com>2011-08-08 08:57:52 -0700
commitd9b84a546cf7968ef7a9e3558c2f0c3d88ba033c (patch)
treea39833fd65311704db8a53971d8d3072a6f6410b /src/rt/rust_chan.cpp
parent86babab2fe92223511042e9cb4b233841cffa054 (diff)
downloadrust-d9b84a546cf7968ef7a9e3558c2f0c3d88ba033c.tar.gz
rust-d9b84a546cf7968ef7a9e3558c2f0c3d88ba033c.zip
Converted the rest of the task-comm-* tests over. Also fixed some
channel lifecycle bugs.
Diffstat (limited to 'src/rt/rust_chan.cpp')
-rw-r--r--src/rt/rust_chan.cpp30
1 files changed, 3 insertions, 27 deletions
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp
index 4b9320688a1..045694eee61 100644
--- a/src/rt/rust_chan.cpp
+++ b/src/rt/rust_chan.cpp
@@ -22,7 +22,7 @@ rust_chan::~rust_chan() {
     KLOG(kernel, comm, "del rust_chan(task=0x%" PRIxPTR ")",
          (uintptr_t) this);
 
-    this->destroy();
+    I(this->kernel, !is_associated());
 
     A(kernel, is_associated() == false,
       "Channel must be disassociated before being freed.");
@@ -32,12 +32,12 @@ rust_chan::~rust_chan() {
  * Link this channel with the specified port.
  */
 void rust_chan::associate(rust_port *port) {
+    this->ref();
     this->port = port;
     scoped_lock with(port->lock);
     KLOG(kernel, task,
          "associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
          this, port);
-    this->ref();
     this->task = port->task;
     this->task->ref();
     this->port->chans.push(this);
@@ -64,7 +64,7 @@ void rust_chan::disassociate() {
     port->chans.swap_delete(this);
 
     // Delete reference to the port.
-    port = NULL;
+     port = NULL;
 
     this->deref();
 }
@@ -99,30 +99,6 @@ rust_chan *rust_chan::clone(rust_task *target) {
         rust_chan(kernel, port, buffer.unit_sz);
 }
 
-/**
- * Cannot Yield: If the task were to unwind, the dropped ref would still
- * appear to be live, causing modify-after-free errors.
- */
-void rust_chan::destroy() {
-    if (is_associated()) {
-        // 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();
-    }
-}
-
 //
 // Local Variables:
 // mode: C++