Detects query cycles by using depth first search over all active query jobs.
If a query cycle is found it will break the cycle by finding an edge which
uses a query latch and then resuming that waiter.
There may be multiple cycles involved in a deadlock, so this searches
all active queries for cycles before finally resuming all the waiters at once.
Finds out if there’s a path to the compiler root (aka. code which isn’t in a query)
from query
without going through any of the queries in visited
.
This is achieved with a depth first search.
Look for query cycles by doing a depth first search starting at query
.
span
is the reason for the query
to execute. This is initially DUMMY_SP.
If a cycle is detected, this initial value is replaced with the span causing
the cycle.
Looks for query cycles starting from the last query in jobs
.
If a cycle is found, all queries in the cycle is removed from jobs
and
the function return true.
If a cycle was not found, the starting query is removed from jobs
and
the function returns false.
Visits all the non-resumable and resumable waiters of a query.
Only waiters in a query are visited.
visit
is called for every waiter and is passed a query waiting on query_ref
and a span indicating the reason the query waited on query_ref
.
If visit
returns Some, this function returns.
For visits of non-resumable waiters it returns the return value of visit
.
For visits of resumable waiters it returns Some(Some(Waiter)) which has the
required information to resume the waiter.
If all visit
calls returns None, this function also returns None.