(cleanup) impl TaskSet
This commit is contained in:
parent
6d9184609a
commit
728edb5af6
2 changed files with 46 additions and 39 deletions
|
|
@ -180,6 +180,13 @@ impl<T> Option<T> {
|
|||
match *self { Some(ref mut x) => Some(f(x)), None => None }
|
||||
}
|
||||
|
||||
/// Maps a `some` value from one type to another by a mutable reference,
|
||||
/// or returns a default value.
|
||||
#[inline]
|
||||
pub fn map_mut_default<'a, U>(&'a mut self, def: U, f: &fn(&'a mut T) -> U) -> U {
|
||||
match *self { Some(ref mut x) => f(x), None => def }
|
||||
}
|
||||
|
||||
/// As `map`, but consumes the option and gives `f` ownership to avoid
|
||||
/// copying.
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -128,21 +128,27 @@ impl IterBytes for TaskHandle {
|
|||
}
|
||||
}
|
||||
|
||||
type TaskSet = HashSet<TaskHandle>;
|
||||
struct TaskSet(HashSet<TaskHandle>);
|
||||
|
||||
fn new_taskset() -> TaskSet {
|
||||
HashSet::new()
|
||||
}
|
||||
fn taskset_insert(tasks: &mut TaskSet, task: TaskHandle) {
|
||||
let didnt_overwrite = tasks.insert(task);
|
||||
assert!(didnt_overwrite);
|
||||
}
|
||||
fn taskset_remove(tasks: &mut TaskSet, task: &TaskHandle) {
|
||||
let was_present = tasks.remove(task);
|
||||
assert!(was_present);
|
||||
}
|
||||
fn taskset_consume(tasks: TaskSet) -> HashSetConsumeIterator<TaskHandle> {
|
||||
tasks.consume()
|
||||
impl TaskSet {
|
||||
#[inline]
|
||||
fn new() -> TaskSet {
|
||||
TaskSet(HashSet::new())
|
||||
}
|
||||
#[inline]
|
||||
fn insert(&mut self, task: TaskHandle) {
|
||||
let didnt_overwrite = (**self).insert(task);
|
||||
assert!(didnt_overwrite);
|
||||
}
|
||||
#[inline]
|
||||
fn remove(&mut self, task: &TaskHandle) {
|
||||
let was_present = (**self).remove(task);
|
||||
assert!(was_present);
|
||||
}
|
||||
#[inline]
|
||||
fn consume(self) -> HashSetConsumeIterator<TaskHandle> {
|
||||
(*self).consume()
|
||||
}
|
||||
}
|
||||
|
||||
// One of these per group of linked-failure tasks.
|
||||
|
|
@ -413,36 +419,30 @@ fn AutoNotify(chan: Chan<TaskResult>) -> AutoNotify {
|
|||
|
||||
fn enlist_in_taskgroup(state: TaskGroupInner, me: TaskHandle,
|
||||
is_member: bool) -> bool {
|
||||
let newstate = util::replace(&mut *state, None);
|
||||
let me = Cell::new(me); // :(
|
||||
// If 'None', the group was failing. Can't enlist.
|
||||
if newstate.is_some() {
|
||||
let mut group = newstate.unwrap();
|
||||
taskset_insert(if is_member {
|
||||
do state.map_mut_default(false) |group| {
|
||||
(if is_member {
|
||||
&mut group.members
|
||||
} else {
|
||||
&mut group.descendants
|
||||
}, me);
|
||||
*state = Some(group);
|
||||
}).insert(me.take());
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
||||
fn leave_taskgroup(state: TaskGroupInner, me: &TaskHandle,
|
||||
is_member: bool) {
|
||||
let newstate = util::replace(&mut *state, None);
|
||||
let me = Cell::new(me); // :(
|
||||
// If 'None', already failing and we've already gotten a kill signal.
|
||||
if newstate.is_some() {
|
||||
let mut group = newstate.unwrap();
|
||||
taskset_remove(if is_member {
|
||||
do state.map_mut |group| {
|
||||
(if is_member {
|
||||
&mut group.members
|
||||
} else {
|
||||
&mut group.descendants
|
||||
}, me);
|
||||
*state = Some(group);
|
||||
}
|
||||
}).remove(me.take());
|
||||
};
|
||||
}
|
||||
|
||||
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
||||
|
|
@ -464,13 +464,13 @@ fn kill_taskgroup(state: TaskGroupInner, me: &TaskHandle, is_main: bool) {
|
|||
if newstate.is_some() {
|
||||
let TaskGroupData { members: members, descendants: descendants } =
|
||||
newstate.unwrap();
|
||||
for taskset_consume(members).advance() |sibling| {
|
||||
for members.consume().advance |sibling| {
|
||||
// Skip self - killing ourself won't do much good.
|
||||
if &sibling != me {
|
||||
RuntimeGlue::kill_task(sibling);
|
||||
}
|
||||
}
|
||||
do taskset_consume(descendants).advance() |child| {
|
||||
for descendants.consume().advance |child| {
|
||||
assert!(&child != me);
|
||||
RuntimeGlue::kill_task(child);
|
||||
}
|
||||
|
|
@ -548,11 +548,11 @@ impl RuntimeGlue {
|
|||
match g {
|
||||
None => {
|
||||
// Main task, doing first spawn ever. Lazily initialise here.
|
||||
let mut members = new_taskset();
|
||||
taskset_insert(&mut members, OldTask(me));
|
||||
let mut members = TaskSet::new();
|
||||
members.insert(OldTask(me));
|
||||
let tasks = exclusive(Some(TaskGroupData {
|
||||
members: members,
|
||||
descendants: new_taskset(),
|
||||
descendants: TaskSet::new(),
|
||||
}));
|
||||
// Main task/group has no ancestors, no notifier, etc.
|
||||
let group = @@mut TCB(tasks, AncestorList(None), true, None);
|
||||
|
|
@ -570,12 +570,12 @@ impl RuntimeGlue {
|
|||
blk(match (*me).taskgroup {
|
||||
None => {
|
||||
// Main task, doing first spawn ever. Lazily initialize.
|
||||
let mut members = new_taskset();
|
||||
let mut members = TaskSet::new();
|
||||
let my_handle = (*me).death.kill_handle.get_ref().clone();
|
||||
taskset_insert(&mut members, NewTask(my_handle));
|
||||
members.insert(NewTask(my_handle));
|
||||
let tasks = exclusive(Some(TaskGroupData {
|
||||
members: members,
|
||||
descendants: new_taskset(),
|
||||
descendants: TaskSet::new(),
|
||||
}));
|
||||
let group = TCB(tasks, AncestorList(None), true, None);
|
||||
(*me).taskgroup = Some(group);
|
||||
|
|
@ -601,8 +601,8 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
|
|||
} else {
|
||||
// Child is in a separate group from spawner.
|
||||
let g = exclusive(Some(TaskGroupData {
|
||||
members: new_taskset(),
|
||||
descendants: new_taskset(),
|
||||
members: TaskSet::new(),
|
||||
descendants: TaskSet::new(),
|
||||
}));
|
||||
let a = if supervised {
|
||||
let new_generation = incr_generation(&ancestors);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue