diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2013-07-22 20:14:15 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2013-07-30 13:19:25 -0400 |
| commit | fa8102ab4afc4deba80344f4a2fdb5861cbe394f (patch) | |
| tree | 85acffb6b6c1e8a36039d49973d14de830a69c41 /src/libstd | |
| parent | 9675cd311a405bd5222597a69825733029a2a040 (diff) | |
| download | rust-fa8102ab4afc4deba80344f4a2fdb5861cbe394f.tar.gz rust-fa8102ab4afc4deba80344f4a2fdb5861cbe394f.zip | |
Unkillable is not unsafe. Close #7832.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rt/select.rs | 44 | ||||
| -rw-r--r-- | src/libstd/task/mod.rs | 44 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 2 |
3 files changed, 45 insertions, 45 deletions
diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs index c2e471a3386..bc9e265c8d9 100644 --- a/src/libstd/rt/select.rs +++ b/src/libstd/rt/select.rs @@ -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,27 +301,25 @@ 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(); - 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()); diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index df927cb6a7a..c26349b220d 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -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() } } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index baebda496dc..749db307012 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -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() } |
