]> git.lizzy.rs Git - rust.git/commitdiff
Unkillable is not unsafe. Close #7832.
authorBen Blum <bblum@andrew.cmu.edu>
Tue, 23 Jul 2013 00:14:15 +0000 (20:14 -0400)
committerBen Blum <bblum@andrew.cmu.edu>
Tue, 30 Jul 2013 17:19:25 +0000 (13:19 -0400)
src/libextra/sync.rs
src/libstd/rt/select.rs
src/libstd/task/mod.rs
src/libstd/task/spawn.rs

index 743c4347a4b4a36571b907d5cbfdc5e9756aec33..47fd4cccb9f98552cb3c23e3253530823d828409 100644 (file)
@@ -130,11 +130,9 @@ pub fn release(&self) {
 impl Sem<()> {
     pub fn access<U>(&self, blk: &fn() -> U) -> U {
         let mut release = None;
-        unsafe {
-            do task::unkillable {
-                self.acquire();
-                release = Some(SemRelease(self));
-            }
+        do task::unkillable {
+            self.acquire();
+            release = Some(SemRelease(self));
         }
         blk()
     }
@@ -153,11 +151,9 @@ fn new_and_signal(count: int, num_condvars: uint)
 
     pub fn access_waitqueue<U>(&self, blk: &fn() -> U) -> U {
         let mut release = None;
-        unsafe {
-            do task::unkillable {
-                self.acquire();
-                release = Some(SemAndSignalRelease(self));
-            }
+        do task::unkillable {
+            self.acquire();
+            release = Some(SemAndSignalRelease(self));
         }
         blk()
     }
@@ -294,17 +290,15 @@ struct CondvarReacquire<'self> {
         #[unsafe_destructor]
         impl<'self> Drop for CondvarReacquire<'self> {
             fn drop(&self) {
-                unsafe {
-                    // Needs to succeed, instead of itself dying.
-                    do task::unkillable {
-                        match self.order {
-                            Just(lock) => do lock.access {
-                                self.sem.acquire();
-                            },
-                            Nothing => {
-                                self.sem.acquire();
-                            },
-                        }
+                // Needs to succeed, instead of itself dying.
+                do task::unkillable {
+                    match self.order {
+                        Just(lock) => do lock.access {
+                            self.sem.acquire();
+                        },
+                        Nothing => {
+                            self.sem.acquire();
+                        },
                     }
                 }
             }
@@ -644,14 +638,12 @@ pub fn write_downgrade<U>(&self, blk: &fn(v: RWLockWriteMode) -> U) -> U {
         // Implementation slightly different from the slicker 'write's above.
         // The exit path is conditional on whether the caller downgrades.
         let mut _release = None;
-        unsafe {
-            do task::unkillable {
-                (&self.order_lock).acquire();
-                (&self.access_lock).acquire();
-                (&self.order_lock).release();
-            }
-            _release = Some(RWLockReleaseDowngrade(self));
+        do task::unkillable {
+            (&self.order_lock).acquire();
+            (&self.access_lock).acquire();
+            (&self.order_lock).release();
         }
+        _release = Some(RWLockReleaseDowngrade(self));
         blk(RWLockWriteMode { lock: self })
     }
 
index c2e471a338625d294ee810bbcaec84a4af5425eb..bc9e265c8d99825ca219e099184316324a3799c0 100644 (file)
@@ -208,7 +208,7 @@ fn select_stream() {
     #[test]
     fn select_unkillable() {
         do run_in_newsched_task {
-            unsafe { do task::unkillable { select_helper(2, [1]) } }
+            do task::unkillable { select_helper(2, [1]) }
         }
     }
 
@@ -243,7 +243,7 @@ fn select_blocking_helper(killable: bool) {
                 if killable {
                     assert!(select(ports) == 1);
                 } else {
-                    unsafe { do task::unkillable { assert!(select(ports) == 1); } }
+                    do task::unkillable { assert!(select(ports) == 1); }
                 }
             }
         }
@@ -287,7 +287,7 @@ fn select_racing_senders_helper(killable: bool, send_on_chans: ~[uint]) {
                         if killable {
                             select(ports);
                         } else {
-                            unsafe { do task::unkillable { select(ports); } }
+                            do task::unkillable { select(ports); }
                         }
                     }
                 }
@@ -301,27 +301,25 @@ fn select_killed() {
             let (success_p, success_c) = oneshot::<bool>();
             let success_c = Cell::new(success_c);
             do task::try {
-                unsafe {
-                    let success_c = Cell::new(success_c.take());
-                    do task::unkillable {
-                        let (p,c) = oneshot();
-                        let c = Cell::new(c);
-                        do task::spawn {
-                            let (dead_ps, dead_cs) = unzip(from_fn(5, |_| oneshot::<()>()));
-                            let mut ports = dead_ps;
-                            select(ports); // should get killed; nothing should leak
-                            c.take().send(()); // must not happen
-                            // Make sure dead_cs doesn't get closed until after select.
-                            let _ = dead_cs;
-                        }
-                        do task::spawn {
-                            fail!(); // should kill sibling awake
-                        }
-
-                        // wait for killed selector to close (NOT send on) its c.
-                        // hope to send 'true'.
-                        success_c.take().send(p.try_recv().is_none());
+                let success_c = Cell::new(success_c.take());
+                do task::unkillable {
+                    let (p,c) = oneshot();
+                    let c = Cell::new(c);
+                    do task::spawn {
+                        let (dead_ps, dead_cs) = unzip(from_fn(5, |_| oneshot::<()>()));
+                        let mut ports = dead_ps;
+                        select(ports); // should get killed; nothing should leak
+                        c.take().send(()); // must not happen
+                        // Make sure dead_cs doesn't get closed until after select.
+                        let _ = dead_cs;
                     }
+                    do task::spawn {
+                        fail!(); // should kill sibling awake
+                    }
+
+                    // wait for killed selector to close (NOT send on) its c.
+                    // hope to send 'true'.
+                    success_c.take().send(p.try_recv().is_none());
                 }
             };
             assert!(success_p.recv());
index df927cb6a7aef4beda47b182664cf9ee75c30e3f..c26349b220d9438a219bbecf07b47c8664e219a7 100644 (file)
@@ -618,32 +618,34 @@ pub fn get_scheduler() -> Scheduler {
  * }
  * ~~~
  */
-pub unsafe fn unkillable<U>(f: &fn() -> U) -> U {
+pub fn unkillable<U>(f: &fn() -> U) -> U {
     use rt::task::Task;
 
-    match context() {
-        OldTaskContext => {
-            let t = rt::rust_get_task();
-            do (|| {
-                rt::rust_task_inhibit_kill(t);
-                f()
-            }).finally {
-                rt::rust_task_allow_kill(t);
+    unsafe {
+        match context() {
+            OldTaskContext => {
+                let t = rt::rust_get_task();
+                do (|| {
+                    rt::rust_task_inhibit_kill(t);
+                    f()
+                }).finally {
+                    rt::rust_task_allow_kill(t);
+                }
             }
-        }
-        TaskContext => {
-            // The inhibits/allows might fail and need to borrow the task.
-            let t = Local::unsafe_borrow::<Task>();
-            do (|| {
-                (*t).death.inhibit_kill((*t).unwinder.unwinding);
-                f()
-            }).finally {
-                (*t).death.allow_kill((*t).unwinder.unwinding);
+            TaskContext => {
+                // The inhibits/allows might fail and need to borrow the task.
+                let t = Local::unsafe_borrow::<Task>();
+                do (|| {
+                    (*t).death.inhibit_kill((*t).unwinder.unwinding);
+                    f()
+                }).finally {
+                    (*t).death.allow_kill((*t).unwinder.unwinding);
+                }
             }
+            // FIXME(#3095): This should be an rtabort as soon as the scheduler
+            // no longer uses a workqueue implemented with an Exclusive.
+            _ => f()
         }
-        // FIXME(#3095): This should be an rtabort as soon as the scheduler
-        // no longer uses a workqueue implemented with an Exclusive.
-        _ => f()
     }
 }
 
index baebda496dce92cbce9d4f5e67f7ef18ec4aac54..749db307012312a6ecad0b1630d1d995babf487d 100644 (file)
@@ -694,7 +694,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
         // Should be run after the local-borrowed task is returned.
         if enlist_success {
             if indestructible {
-                unsafe { do unkillable { f() } }
+                do unkillable { f() }
             } else {
                 f()
             }