about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2013-08-07 20:26:15 -0400
committerBen Blum <bblum@andrew.cmu.edu>2013-08-12 13:19:17 -0400
commitee5cfb0c2dae046bac18e42231074d5063b1e740 (patch)
treeb26d5a0399da24fe071e471be09054d340c4a14d /src/libstd
parentecfc9a82231eef47bf522e6d18138a0f3414d914 (diff)
downloadrust-ee5cfb0c2dae046bac18e42231074d5063b1e740.tar.gz
rust-ee5cfb0c2dae046bac18e42231074d5063b1e740.zip
Don't use unkillable in UnsafeArc dtor when there's no unwrapper. Close #8382.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/unstable/sync.rs40
1 files changed, 21 insertions, 19 deletions
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index a9dded41683..adbf9fc7578 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -229,20 +229,22 @@ impl<T> Drop for UnsafeAtomicRcBox<T>{
             if self.data.is_null() {
                 return; // Happens when destructing an unwrapper's handle.
             }
-            do task::unkillable {
-                let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
-                // Must be acquire+release, not just release, to make sure this
-                // doesn't get reordered to after the unwrapper pointer load.
-                let old_count = data.count.fetch_sub(1, SeqCst);
-                assert!(old_count >= 1);
-                if old_count == 1 {
-                    // Were we really last, or should we hand off to an
-                    // unwrapper? It's safe to not xchg because the unwrapper
-                    // will set the unwrap lock *before* dropping his/her
-                    // reference. In effect, being here means we're the only
-                    // *awake* task with the data.
-                    match data.unwrapper.take(Acquire) {
-                        Some(~(message,response)) => {
+            let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
+            // Must be acquire+release, not just release, to make sure this
+            // doesn't get reordered to after the unwrapper pointer load.
+            let old_count = data.count.fetch_sub(1, SeqCst);
+            assert!(old_count >= 1);
+            if old_count == 1 {
+                // Were we really last, or should we hand off to an
+                // unwrapper? It's safe to not xchg because the unwrapper
+                // will set the unwrap lock *before* dropping his/her
+                // reference. In effect, being here means we're the only
+                // *awake* task with the data.
+                match data.unwrapper.take(Acquire) {
+                    Some(~(message,response)) => {
+                        let cell = Cell::new((message, response, data));
+                        do task::unkillable {
+                            let (message, response, data) = cell.take();
                             // Send 'ready' and wait for a response.
                             message.send(());
                             // Unkillable wait. Message guaranteed to come.
@@ -253,13 +255,13 @@ impl<T> Drop for UnsafeAtomicRcBox<T>{
                                 // Other task was killed. drop glue takes over.
                             }
                         }
-                        None => {
-                            // drop glue takes over.
-                        }
                     }
-                } else {
-                    cast::forget(data);
+                    None => {
+                        // drop glue takes over.
+                    }
                 }
+            } else {
+                cast::forget(data);
             }
         }
     }