Unkillable is not unsafe. Close #7832.

This commit is contained in:
Ben Blum 2013-07-22 20:14:15 -04:00
parent 9675cd311a
commit fa8102ab4a
4 changed files with 65 additions and 73 deletions

View File

@ -130,12 +130,10 @@ impl<Q:Send> Sem<Q> {
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));
}
}
blk()
}
}
@ -153,12 +151,10 @@ impl Sem<~[WaitQueue]> {
pub fn access_waitqueue<U>(&self, blk: &fn() -> U) -> U {
let mut release = None;
unsafe {
do task::unkillable {
self.acquire();
release = Some(SemAndSignalRelease(self));
}
}
blk()
}
}
@ -294,7 +290,6 @@ impl<'self> Condvar<'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 {
@ -309,7 +304,6 @@ impl<'self> Condvar<'self> {
}
}
}
}
/// Wake up a blocked task. Returns false if there was no blocked task.
pub fn signal(&self) -> bool { self.signal_on(0) }
@ -644,14 +638,12 @@ impl RWLock {
// 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));
}
blk(RWLockWriteMode { lock: self })
}

View File

@ -208,7 +208,7 @@ mod test {
#[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 @@ mod test {
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 @@ mod test {
if killable {
select(ports);
} else {
unsafe { do task::unkillable { select(ports); } }
do task::unkillable { select(ports); }
}
}
}
@ -301,7 +301,6 @@ mod test {
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();
@ -322,7 +321,6 @@ mod test {
// hope to send 'true'.
success_c.take().send(p.try_recv().is_none());
}
}
};
assert!(success_p.recv());
}

View File

@ -618,9 +618,10 @@ 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;
unsafe {
match context() {
OldTaskContext => {
let t = rt::rust_get_task();
@ -646,6 +647,7 @@ pub unsafe fn unkillable<U>(f: &fn() -> U) -> U {
_ => f()
}
}
}
/// The inverse of unkillable. Only ever to be used nested in unkillable().
pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {

View 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()
}