Make failure propagation to dead parents work
The failure will basically go 'through' the dead parent and continue propagating the failure (as if the child was reparented).
This commit is contained in:
parent
6dcd0a9b5e
commit
103197bc42
5 changed files with 81 additions and 3 deletions
|
@ -273,6 +273,7 @@ void
|
|||
rust_task::kill() {
|
||||
if (dead()) {
|
||||
// Task is already dead, can't kill what's already dead.
|
||||
fail_parent();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -308,6 +309,14 @@ rust_task::conclude_failure() {
|
|||
die();
|
||||
// Unblock the task so it can unwind.
|
||||
unblock();
|
||||
fail_parent();
|
||||
failed = true;
|
||||
notify_tasks_waiting_to_join();
|
||||
yield(4);
|
||||
}
|
||||
|
||||
void
|
||||
rust_task::fail_parent() {
|
||||
if (supervisor) {
|
||||
DLOG(sched, task,
|
||||
"task %s @0x%" PRIxPTR
|
||||
|
@ -318,9 +327,6 @@ rust_task::conclude_failure() {
|
|||
// FIXME: implement unwinding again.
|
||||
if (NULL == supervisor && propagate_failure)
|
||||
sched->fail();
|
||||
failed = true;
|
||||
notify_tasks_waiting_to_join();
|
||||
yield(4);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -158,6 +158,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
|||
// Fail self, assuming caller-on-stack is this task.
|
||||
void fail();
|
||||
void conclude_failure();
|
||||
void fail_parent();
|
||||
|
||||
// Disconnect from our supervisor.
|
||||
void unsupervise();
|
||||
|
|
17
src/test/run-fail/linked-failure2.rs
Normal file
17
src/test/run-fail/linked-failure2.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// -*- rust -*-
|
||||
|
||||
// error-pattern:fail
|
||||
use std;
|
||||
import std::task;
|
||||
import std::comm::chan;
|
||||
import std::comm::port;
|
||||
import std::comm::recv;
|
||||
|
||||
fn child() { fail; }
|
||||
|
||||
fn main() {
|
||||
let p = port::<int>();
|
||||
let f = child;
|
||||
task::spawn(f);
|
||||
task::yield();
|
||||
}
|
23
src/test/run-fail/linked-failure3.rs
Normal file
23
src/test/run-fail/linked-failure3.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// -*- rust -*-
|
||||
|
||||
// error-pattern:fail
|
||||
use std;
|
||||
import std::task;
|
||||
import std::comm::port;
|
||||
import std::comm::recv;
|
||||
|
||||
fn grandchild() { fail; }
|
||||
|
||||
fn child() {
|
||||
let p = port::<int>();
|
||||
let f = grandchild;
|
||||
task::spawn(f);
|
||||
let x = recv(p);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p = port::<int>();
|
||||
let f = child;
|
||||
task::spawn(f);
|
||||
let x = recv(p);
|
||||
}
|
31
src/test/run-fail/linked-failure4.rs
Normal file
31
src/test/run-fail/linked-failure4.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// -*- rust -*-
|
||||
// xfail-test
|
||||
// error-pattern:1 == 2
|
||||
use std;
|
||||
import std::task;
|
||||
import std::comm::chan;
|
||||
import std::comm::port;
|
||||
import std::comm::recv;
|
||||
|
||||
fn child() { assert (1 == 2); }
|
||||
|
||||
fn parent() {
|
||||
let p = port::<int>();
|
||||
let f = child;
|
||||
task::spawn(f);
|
||||
let x = recv(p);
|
||||
}
|
||||
|
||||
// This task is not linked to the failure chain, but since the other
|
||||
// tasks are going to fail the kernel, this one will fail too
|
||||
fn sleeper() {
|
||||
let p = port::<int>();
|
||||
let x = recv(p);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = parent;
|
||||
let g = sleeper;
|
||||
task::spawn(f);
|
||||
task::spawn(g);
|
||||
}
|
Loading…
Reference in a new issue