fix deadlock in file.rs

This commit is contained in:
Folkert 2020-11-10 20:15:38 +01:00
parent 3aa6455795
commit 6490956a84

View file

@ -293,7 +293,7 @@ struct ModuleCache<'a> {
sources: MutMap<ModuleId, (PathBuf, &'a str)>,
}
fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) -> BuildTask<'a> {
fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) -> Vec<BuildTask<'a>> {
// we blindly assume all dependencies are met
match state.dependencies.status.get_mut(&(module_id, phase)) {
@ -301,11 +301,20 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
// start this phase!
*current = Status::Pending;
}
Some(Status::Pending) | Some(Status::Done) => {
Some(Status::Pending) => {
// don't start this task again!
todo!();
return vec![];
}
Some(Status::Done) => {
// don't start this task again, but tell those waiting for it they can continue
return state
.dependencies
.notify(module_id, phase)
.into_iter()
.map(|(module_id, phase)| start_phase(module_id, phase, state))
.flatten()
.collect();
}
None => match phase {
Phase::LoadHeader => {
// this is fine, mark header loading as pending
@ -321,6 +330,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
},
}
let task = {
match phase {
Phase::LoadHeader => {
let dep_name = state
@ -350,7 +360,8 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
let deps_by_name = &parsed.deps_by_name;
let num_deps = deps_by_name.len();
let mut dep_idents: MutMap<ModuleId, IdentIds> = IdentIds::exposed_builtins(num_deps);
let mut dep_idents: MutMap<ModuleId, IdentIds> =
IdentIds::exposed_builtins(num_deps);
let State {
ident_ids_by_module,
@ -496,6 +507,9 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
}
}
}
};
vec![task]
}
#[derive(Debug)]
@ -1329,6 +1343,21 @@ where
.unwrap()
}
fn start_tasks<'a>(
work: MutSet<(ModuleId, Phase)>,
state: &mut State<'a>,
injector: &Injector<BuildTask<'a>>,
worker_listeners: &'a [Sender<WorkerMsg>],
) -> Result<(), LoadingProblem> {
for (module_id, phase) in work {
for task in start_phase(module_id, phase, state) {
enqueue_task(&injector, worker_listeners, task)?
}
}
Ok(())
}
fn update<'a>(
mut state: State<'a>,
msg: Msg<'a>,
@ -1384,19 +1413,11 @@ fn update<'a>(
state.module_cache.headers.insert(header.module_id, header);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
let work = state.dependencies.notify(home, Phase::LoadHeader);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
Ok(state)
}
@ -1412,11 +1433,7 @@ fn update<'a>(
let work = state.dependencies.notify(module_id, Phase::Parse);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
Ok(state)
}
@ -1452,11 +1469,7 @@ fn update<'a>(
.dependencies
.notify(module_id, Phase::CanonicalizeAndConstrain);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
Ok(state)
}
@ -1503,11 +1516,7 @@ fn update<'a>(
.notify(module_id, Phase::CanonicalizeAndConstrain),
);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
Ok(state)
}
@ -1594,11 +1603,7 @@ fn update<'a>(
state.constrained_ident_ids.insert(module_id, ident_ids);
}
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
}
Ok(state)
@ -1646,11 +1651,8 @@ fn update<'a>(
.dependencies
.notify(module_id, Phase::FindSpecializations);
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
start_tasks(work, &mut state, &injector, worker_listeners)?;
enqueue_task(&injector, worker_listeners, task)?
}
Ok(state)
}
MadeSpecializations {
@ -1718,11 +1720,7 @@ fn update<'a>(
// the originally requested module, we're all done!
return Ok(state);
} else {
for (module_id, phase) in work {
let task = start_phase(module_id, phase, &mut state);
enqueue_task(&injector, worker_listeners, task)?
}
start_tasks(work, &mut state, &injector, worker_listeners)?;
}
Ok(state)