diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-01-11 17:38:09 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-01-11 17:38:09 +0100 |
commit | dc79e956b628bb71a3ecbfdab6edd19ce6cf918f (patch) | |
tree | d1770397e511ed3f230e03d983bc4c3c7cb1e36c /core/io/resource_loader.cpp | |
parent | 9e967ebdf90e32fb93a7895a19a4111e72d9c660 (diff) | |
parent | a7317748135e064ff150072f2f46ccc1d2c4b358 (diff) | |
download | redot-engine-dc79e956b628bb71a3ecbfdab6edd19ce6cf918f.tar.gz |
Merge pull request #86587 from RandomShaper/wtp_enhance
Enhance & fix `WorkerThreadPool`
Diffstat (limited to 'core/io/resource_loader.cpp')
-rw-r--r-- | core/io/resource_loader.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 1fbb6ff2ed..ba11d84bce 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -630,15 +630,16 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro if (load_task.task_id != 0) { // Loading thread is in the worker pool. - load_task.awaited = true; thread_load_mutex.unlock(); Error err = WorkerThreadPool::get_singleton()->wait_for_task_completion(load_task.task_id); if (err == ERR_BUSY) { - // The WorkerThreadPool has scheduled tasks in a way that the current load depends on - // another one in a lower stack frame. Restart such load here. When the stack is eventually - // unrolled, the original load will have been notified to go on. + // The WorkerThreadPool has reported that the current task wants to await on an older one. + // That't not allowed for safety, to avoid deadlocks. Fortunately, though, in the context of + // resource loading that means that the task to wait for can be restarted here to break the + // cycle, with as much recursion into this process as needed. + // When the stack is eventually unrolled, the original load will have been notified to go on. #ifdef DEV_ENABLED - print_verbose("ResourceLoader: Load task happened to wait on another one deep in the call stack. Attempting to avoid deadlock by re-issuing the load now."); + print_verbose("ResourceLoader: Potential for deadlock detected in task dependency. Attempting to avoid it by re-issuing the load now."); #endif // CACHE_MODE_IGNORE is needed because, otherwise, the new request would just see there's // an ongoing load for that resource and wait for it again. This value forces a new load. @@ -652,6 +653,7 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro } else { DEV_ASSERT(err == OK); thread_load_mutex.lock(); + load_task.awaited = true; } } else { // Loading thread is main or user thread. |