diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-05-15 11:34:52 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-05-15 16:13:42 -0700 |
| commit | 7277cd71984e6a09bc2f8a8a828a5e213b485d00 (patch) | |
| tree | 1bab4372580c8f39c7514923f13fef9da33219e8 /src/libcore/task.rs | |
| parent | 8fe0461f06ac4a7fe9705d2cd62e8bb547975c8f (diff) | |
| download | rust-7277cd71984e6a09bc2f8a8a828a5e213b485d00.tar.gz rust-7277cd71984e6a09bc2f8a8a828a5e213b485d00.zip | |
core: Add task::unkillable
Diffstat (limited to 'src/libcore/task.rs')
| -rw-r--r-- | src/libcore/task.rs | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 2c91b0de011..b9a07a7625b 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -51,7 +51,7 @@ export try; export yield; export failing; export get_task; - +export unkillable; /* Data types */ @@ -467,6 +467,29 @@ fn get_task() -> task { task(rustrt::get_task_id()) } +#[doc = " +Temporarily make the task unkillable + +# Example + + task::unkillable {|| + // detach / yield / destroy must all be called together + rustrt::rust_port_detach(po); + // This must not result in the current task being killed + task::yield(); + rustrt::rust_port_destroy(po); + } + +"] +unsafe fn unkillable(f: fn()) { + resource allow_failure(_i: ()) { + rustrt::rust_task_allow_kill(); + } + let _allow_failure = allow_failure(()); + rustrt::rust_task_inhibit_kill(); + f(); +} + /* Internal */ @@ -566,6 +589,8 @@ native mod rustrt { fn rust_task_is_unwinding(rt: *rust_task) -> bool; fn unsupervise(); fn rust_osmain_sched_id() -> sched_id; + fn rust_task_inhibit_kill(); + fn rust_task_allow_kill(); } @@ -930,3 +955,39 @@ fn test_osmain() { } comm::recv(po); } + +#[test] +#[ignore(cfg(target_os = "win32"))] +#[should_fail] +fn test_unkillable() unsafe { + import comm::methods; + let po = comm::port(); + let ch = po.chan(); + + // We want to do this after failing + spawn {|| + iter::repeat(10u, yield); + ch.send(()); + } + + spawn {|| + yield(); + // We want to fail after the unkillable task + // blocks on recv + fail; + } + + unkillable {|| + let p = ~0; + let pp: *uint = unsafe::reinterpret_cast(p); + unsafe::forget(p); + + // If we are killed here then the box will leak + po.recv(); + + let _p: ~int = unsafe::reinterpret_cast(pp); + } + + // Now we can be killed + po.recv(); +} |
