Skip to content

Commit a0d42bb

Browse files
committed
Unkillable is not unsafe. Close rust-lang#7832.
1 parent 4f9f1e4 commit a0d42bb

File tree

4 files changed

+65
-73
lines changed

4 files changed

+65
-73
lines changed

src/libextra/sync.rs

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,9 @@ impl<Q:Send> Sem<Q> {
130130
impl Sem<()> {
131131
pub fn access<U>(&self, blk: &fn() -> U) -> U {
132132
let mut release = None;
133-
unsafe {
134-
do task::unkillable {
135-
self.acquire();
136-
release = Some(SemRelease(self));
137-
}
133+
do task::unkillable {
134+
self.acquire();
135+
release = Some(SemRelease(self));
138136
}
139137
blk()
140138
}
@@ -153,11 +151,9 @@ impl Sem<~[WaitQueue]> {
153151

154152
pub fn access_waitqueue<U>(&self, blk: &fn() -> U) -> U {
155153
let mut release = None;
156-
unsafe {
157-
do task::unkillable {
158-
self.acquire();
159-
release = Some(SemAndSignalRelease(self));
160-
}
154+
do task::unkillable {
155+
self.acquire();
156+
release = Some(SemAndSignalRelease(self));
161157
}
162158
blk()
163159
}
@@ -294,17 +290,15 @@ impl<'self> Condvar<'self> {
294290
#[unsafe_destructor]
295291
impl<'self> Drop for CondvarReacquire<'self> {
296292
fn drop(&self) {
297-
unsafe {
298-
// Needs to succeed, instead of itself dying.
299-
do task::unkillable {
300-
match self.order {
301-
Just(lock) => do lock.access {
302-
self.sem.acquire();
303-
},
304-
Nothing => {
305-
self.sem.acquire();
306-
},
307-
}
293+
// Needs to succeed, instead of itself dying.
294+
do task::unkillable {
295+
match self.order {
296+
Just(lock) => do lock.access {
297+
self.sem.acquire();
298+
},
299+
Nothing => {
300+
self.sem.acquire();
301+
},
308302
}
309303
}
310304
}
@@ -644,14 +638,12 @@ impl RWLock {
644638
// Implementation slightly different from the slicker 'write's above.
645639
// The exit path is conditional on whether the caller downgrades.
646640
let mut _release = None;
647-
unsafe {
648-
do task::unkillable {
649-
(&self.order_lock).acquire();
650-
(&self.access_lock).acquire();
651-
(&self.order_lock).release();
652-
}
653-
_release = Some(RWLockReleaseDowngrade(self));
641+
do task::unkillable {
642+
(&self.order_lock).acquire();
643+
(&self.access_lock).acquire();
644+
(&self.order_lock).release();
654645
}
646+
_release = Some(RWLockReleaseDowngrade(self));
655647
blk(RWLockWriteMode { lock: self })
656648
}
657649

src/libstd/rt/select.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ mod test {
208208
#[test]
209209
fn select_unkillable() {
210210
do run_in_newsched_task {
211-
unsafe { do task::unkillable { select_helper(2, [1]) } }
211+
do task::unkillable { select_helper(2, [1]) }
212212
}
213213
}
214214

@@ -243,7 +243,7 @@ mod test {
243243
if killable {
244244
assert!(select(ports) == 1);
245245
} else {
246-
unsafe { do task::unkillable { assert!(select(ports) == 1); } }
246+
do task::unkillable { assert!(select(ports) == 1); }
247247
}
248248
}
249249
}
@@ -287,7 +287,7 @@ mod test {
287287
if killable {
288288
select(ports);
289289
} else {
290-
unsafe { do task::unkillable { select(ports); } }
290+
do task::unkillable { select(ports); }
291291
}
292292
}
293293
}
@@ -301,27 +301,25 @@ mod test {
301301
let (success_p, success_c) = oneshot::<bool>();
302302
let success_c = Cell::new(success_c);
303303
do task::try {
304-
unsafe {
305-
let success_c = Cell::new(success_c.take());
306-
do task::unkillable {
307-
let (p,c) = oneshot();
308-
let c = Cell::new(c);
309-
do task::spawn {
310-
let (dead_ps, dead_cs) = unzip(from_fn(5, |_| oneshot::<()>()));
311-
let mut ports = dead_ps;
312-
select(ports); // should get killed; nothing should leak
313-
c.take().send(()); // must not happen
314-
// Make sure dead_cs doesn't get closed until after select.
315-
let _ = dead_cs;
316-
}
317-
do task::spawn {
318-
fail!(); // should kill sibling awake
319-
}
320-
321-
// wait for killed selector to close (NOT send on) its c.
322-
// hope to send 'true'.
323-
success_c.take().send(p.try_recv().is_none());
304+
let success_c = Cell::new(success_c.take());
305+
do task::unkillable {
306+
let (p,c) = oneshot();
307+
let c = Cell::new(c);
308+
do task::spawn {
309+
let (dead_ps, dead_cs) = unzip(from_fn(5, |_| oneshot::<()>()));
310+
let mut ports = dead_ps;
311+
select(ports); // should get killed; nothing should leak
312+
c.take().send(()); // must not happen
313+
// Make sure dead_cs doesn't get closed until after select.
314+
let _ = dead_cs;
324315
}
316+
do task::spawn {
317+
fail!(); // should kill sibling awake
318+
}
319+
320+
// wait for killed selector to close (NOT send on) its c.
321+
// hope to send 'true'.
322+
success_c.take().send(p.try_recv().is_none());
325323
}
326324
};
327325
assert!(success_p.recv());

src/libstd/task/mod.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -618,32 +618,34 @@ pub fn get_scheduler() -> Scheduler {
618618
* }
619619
* ~~~
620620
*/
621-
pub unsafe fn unkillable<U>(f: &fn() -> U) -> U {
621+
pub fn unkillable<U>(f: &fn() -> U) -> U {
622622
use rt::task::Task;
623623

624-
match context() {
625-
OldTaskContext => {
626-
let t = rt::rust_get_task();
627-
do (|| {
628-
rt::rust_task_inhibit_kill(t);
629-
f()
630-
}).finally {
631-
rt::rust_task_allow_kill(t);
624+
unsafe {
625+
match context() {
626+
OldTaskContext => {
627+
let t = rt::rust_get_task();
628+
do (|| {
629+
rt::rust_task_inhibit_kill(t);
630+
f()
631+
}).finally {
632+
rt::rust_task_allow_kill(t);
633+
}
632634
}
633-
}
634-
TaskContext => {
635-
// The inhibits/allows might fail and need to borrow the task.
636-
let t = Local::unsafe_borrow::<Task>();
637-
do (|| {
638-
(*t).death.inhibit_kill((*t).unwinder.unwinding);
639-
f()
640-
}).finally {
641-
(*t).death.allow_kill((*t).unwinder.unwinding);
635+
TaskContext => {
636+
// The inhibits/allows might fail and need to borrow the task.
637+
let t = Local::unsafe_borrow::<Task>();
638+
do (|| {
639+
(*t).death.inhibit_kill((*t).unwinder.unwinding);
640+
f()
641+
}).finally {
642+
(*t).death.allow_kill((*t).unwinder.unwinding);
643+
}
642644
}
645+
// FIXME(#3095): This should be an rtabort as soon as the scheduler
646+
// no longer uses a workqueue implemented with an Exclusive.
647+
_ => f()
643648
}
644-
// FIXME(#3095): This should be an rtabort as soon as the scheduler
645-
// no longer uses a workqueue implemented with an Exclusive.
646-
_ => f()
647649
}
648650
}
649651

src/libstd/task/spawn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
694694
// Should be run after the local-borrowed task is returned.
695695
if enlist_success {
696696
if indestructible {
697-
unsafe { do unkillable { f() } }
697+
do unkillable { f() }
698698
} else {
699699
f()
700700
}

0 commit comments

Comments
 (0)