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.