refactor(#2500): encapsulate the jobq lock, drop the dead borrowed-guard layer

Make the resource lock unmisusable from outside the crate: the public
surface is now purely declarative (build a Graph with Dep::Resource edges,
configure capacities, run the Scheduler), and the scheduler owns every
acquire/release — a consumer never holds a guard, so it cannot hold the
lock wrong.

- `guard` module + `ResourceTable::try_acquire_all`/`release_all` +
  `Graph::set_state` are now `pub(crate)`.
- Remove the dead borrowed-guard layer (`ResourceGuard::borrowed`,
  `Acq::Borrowed`, `is_owning`): the scheduler tracks re-entrancy via its
  own single borrow slot per (holder, resource) and never constructs a
  borrowed guard, so re-entrancy lives in exactly one place. `Acq`
  collapses into the owning `ResourceGuard` struct.
- `#[must_use]` on `Scheduler::settle` — ignoring its ids silently drops
  runnable work.
- `SharedResources::with` (test-only table observability) is `#[cfg(test)]`.
- Drop the moot borrowed-guard tests; retained owning tests are black-box,
  and the redundant `set_state` test helper is gone.
This commit is contained in:
atlas 2026-07-19 14:40:25 +02:00 committed by mara
commit f64ab47de0
4 changed files with 41 additions and 111 deletions

View file

@ -90,6 +90,7 @@ impl<N, R: Clone + Eq + Hash> Scheduler<N, R> {
/// returned for the runner to execute. A single pass suffices — a node
/// started here is `Running`, not terminal, so it cannot satisfy another
/// node's dependency in the same pass; it only consumes resources.
#[must_use]
pub fn settle(&mut self) -> Vec<NodeId> {
let pending: Vec<NodeId> = self
.graph