about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlaper Fesp <flaper87@gmail.com>2013-08-18 00:51:39 +0200
committerFlaper Fesp <flaper87@gmail.com>2013-08-27 00:34:16 +0200
commitcd92d2c77fe420568045bdc41b4acc4265408eb7 (patch)
tree411b81105b25aea869014104148699a1f43fbe74 /src
parent9cd91c8cc4e87f3abd9201515eefe24f0124810c (diff)
downloadrust-cd92d2c77fe420568045bdc41b4acc4265408eb7.tar.gz
rust-cd92d2c77fe420568045bdc41b4acc4265408eb7.zip
Make rekillable consistent with unkillable
As for now, rekillable is an unsafe function, instead, it should behave
just like unkillable by encapsulating unsafe code within an unsafe
block.

This patch does that and removes unsafe blocks that were encapsulating
rekillable calls throughout rust's libs.

Fixes #8232
Diffstat (limited to 'src')
-rw-r--r--src/libextra/sync.rs48
-rw-r--r--src/libstd/task/mod.rs43
2 files changed, 46 insertions, 45 deletions
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index afb4cf3943a..1952c35eb9d 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -135,9 +135,7 @@ impl<Q:Send> Sem<Q> {
         do task::unkillable {
             do (|| {
                 self.acquire();
-                unsafe {
-                    do task::rekillable { blk() }
-                }
+                do task::rekillable { blk() }
             }).finally {
                 self.release();
             }
@@ -234,10 +232,8 @@ impl<'self> Condvar<'self> {
                 // signaller already sent -- I mean 'unconditionally' in contrast
                 // with acquire().)
                 do (|| {
-                    unsafe {
-                        do task::rekillable {
-                            let _ = WaitEnd.take_unwrap().recv();
-                        }
+                    do task::rekillable {
+                        let _ = WaitEnd.take_unwrap().recv();
                     }
                 }).finally {
                     // Reacquire the condvar. Note this is back in the unkillable
@@ -516,14 +512,12 @@ impl RWLock {
      * 'write' from other tasks will run concurrently with this one.
      */
     pub fn write<U>(&self, blk: &fn() -> U) -> U {
-        unsafe {
-            do task::unkillable {
-                (&self.order_lock).acquire();
-                do (&self.access_lock).access {
-                    (&self.order_lock).release();
-                    do task::rekillable {
-                        blk()
-                    }
+        do task::unkillable {
+            (&self.order_lock).acquire();
+            do (&self.access_lock).access {
+                (&self.order_lock).release();
+                do task::rekillable {
+                    blk()
                 }
             }
         }
@@ -562,16 +556,14 @@ impl RWLock {
         // which can't happen until T2 finishes the downgrade-read entirely.
         // The astute reader will also note that making waking writers use the
         // order_lock is better for not starving readers.
-        unsafe {
-            do task::unkillable {
-                (&self.order_lock).acquire();
-                do (&self.access_lock).access_cond |cond| {
-                    (&self.order_lock).release();
-                    do task::rekillable {
-                        let opt_lock = Just(&self.order_lock);
-                        blk(&Condvar { sem: cond.sem, order: opt_lock,
-                                       token: NonCopyable::new() })
-                    }
+        do task::unkillable {
+            (&self.order_lock).acquire();
+            do (&self.access_lock).access_cond |cond| {
+                (&self.order_lock).release();
+                do task::rekillable {
+                    let opt_lock = Just(&self.order_lock);
+                    blk(&Condvar { sem: cond.sem, order: opt_lock,
+                                   token: NonCopyable::new() })
                 }
             }
         }
@@ -606,10 +598,8 @@ impl RWLock {
             (&self.access_lock).acquire();
             (&self.order_lock).release();
             do (|| {
-                unsafe {
-                    do task::rekillable {
-                        blk(RWLockWriteMode { lock: self, token: NonCopyable::new() })
-                    }
+                do task::rekillable {
+                    blk(RWLockWriteMode { lock: self, token: NonCopyable::new() })
                 }
             }).finally {
                 let writer_or_last_reader;
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index e76b81a904d..bac4991d858 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -597,21 +597,34 @@ pub fn unkillable<U>(f: &fn() -> U) -> U {
     }
 }
 
-/// The inverse of unkillable. Only ever to be used nested in unkillable().
-pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
+/**
+ * Makes killable a task marked as unkillable
+ *
+ * # Example
+ *
+ * ~~~
+ * do task::unkillable {
+ *     do task::rekillable {
+ *          // Task is killable
+ *     }
+ * }
+ */
+pub fn rekillable<U>(f: &fn() -> U) -> U {
     use rt::task::Task;
 
-    if in_green_task_context() {
-        let t = Local::unsafe_borrow::<Task>();
-        do (|| {
-            (*t).death.allow_kill((*t).unwinder.unwinding);
+    unsafe {
+        if in_green_task_context() {
+            let t = Local::unsafe_borrow::<Task>();
+            do (|| {
+                (*t).death.allow_kill((*t).unwinder.unwinding);
+                f()
+            }).finally {
+                (*t).death.inhibit_kill((*t).unwinder.unwinding);
+            }
+        } else {
+            // FIXME(#3095): As in unkillable().
             f()
-        }).finally {
-            (*t).death.inhibit_kill((*t).unwinder.unwinding);
         }
-    } else {
-        // FIXME(#3095): As in unkillable().
-        f()
     }
 }
 
@@ -646,11 +659,9 @@ fn test_kill_rekillable_task() {
     do run_in_newsched_task {
         do task::try {
             do task::unkillable {
-                unsafe {
-                    do task::rekillable {
-                        do task::spawn {
-                            fail!();
-                        }
+                do task::rekillable {
+                    do task::spawn {
+                        fail!();
                     }
                 }
             }