Avoid multiple possibilites of deadlock in resource loading #77143
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Multi-threaded resource loading can deadlock if one of the current load tasks are waiting for another which hasn't still started running to complete and all the low-priority slots in the
WorkerThreadPool
are occupied. This PR allows theWorkerThreadPool
to detect such a situation and schedule additional low-prio tasks until the situation is solved.Since the
WorkerThreadPool
needs to count how many low-prio threads are awaiting on others, this PR also needed to add support for multiple waiters. Otherwise, theResourceLoader
would use its own waiting mechanism for tasks already awaited, which would prevent such count from being exhaustive.Another possibility of deadlock is that a worker thread in the
WorkerThreadPool
, upon one task waiting for another, runs yet another task over the stack frame of the awaiting one. That can lead to a load task eventually waiting for a previous one which can no longer finish because it's "buried" in the stack. Many possibilites have been assessed and discarded (enrich the worker pool with some task dependency info, avoid burying tasks' stack frames and even adding support for fibers for easy task switching within a given thread). The approach here is let theWorkerThreadPool
detect the fact and reportERR_BUSY
to the caller. In this PR theResourceLoader
is trained to catch the problem and apply a workaround.This PR also ensures there's always at least one high-priority thread in the pool.