summary refs log tree commit diff
path: root/src/rt/rust_chan.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-28 14:00:56 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-28 14:25:20 -0700
commit4b356097c288cc01dd1c7abd9434b48071d95b49 (patch)
tree8bb25b1f8a20a17b3e4d59e998c0ebfb115c9d3d /src/rt/rust_chan.cpp
parent12ab65107a96207063814c392d64e18e718c0a45 (diff)
Change the locking rules around channel disassociation again
This prevents port's destructor from accessing a deleted channel
Diffstat (limited to 'src/rt/rust_chan.cpp')
-rw-r--r--src/rt/rust_chan.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp
index 44d45f693e7..e32c4214afc 100644
--- a/src/rt/rust_chan.cpp
+++ b/src/rt/rust_chan.cpp
@@ -51,9 +51,9 @@ bool rust_chan::is_associated() {
  * Unlink this channel from its associated port.
  */
 void rust_chan::disassociate() {
+    // Precondition: port->referent()->lock must be held
     A(kernel, is_associated(),
       "Channel must be associated with a port.");
-    scoped_lock with(port->referent()->lock);
     if (port->is_proxy() == false) {
         KLOG(kernel, task,
              "disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
@@ -127,6 +127,7 @@ void rust_chan::destroy() {
             // 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 {
@@ -143,6 +144,7 @@ void rust_chan::destroy() {
             if (buffer.is_empty() == false) {
                 return;
             }
+            scoped_lock with(port->referent()->lock);
             disassociate();
         }
     }