Description
Currently the function reparent_children_to
in rt/kill.rs
creates tombstones as a "lazy list" of heap closures that capture each other in their environments. Such a tombstone is one of two closure values (where in both cases, others
has type Cell<Option<~fn() -> bool>>
):
|| {
// Prefer to check tombstones that were there first,
// being "more fair" at the expense of tail-recursion.
others.take().map_consume_default(true, |f| f()) && {
let mut inner = this.take().unwrap();
(!inner.any_child_failed) &&
inner.child_tombstones.take_map_default(true, |f| f())
}
}
|| {
// Prefer fairness to tail-recursion, as in above case.
others.take().map_consume_default(true, |f| f()) &&
f.take()()
}
However, as noted, this can stack overflow, and since we don't guarantee tail-call optimization, even making it tail-recursive isn't reliable(?). A way to expose this is to edit task-perf-jargon-metal-smoke.rs
to use spawn
instead of spawn_supervised
(which enables this exit-status-watching code).
To fix this, the tombstones should be changed to a struct. When storing them in the list, since there are two possible types of tombstones, they can either be packed as a trait or stored in an Either (probably the latter is better).