diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-06 22:38:41 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-06 22:38:41 +0200 |
commit | effbc0797652a79987257c22c730c123046e8434 (patch) | |
tree | af8e47ba1e2de898e5853562a763ec4843922550 | |
parent | a6db33ef8956b6dcbcf48e99cd3f6d0c816741ff (diff) | |
parent | ccd470d33c49e28d5be3ca258da4f2ce950949db (diff) | |
download | redot-engine-effbc0797652a79987257c22c730c123046e8434.tar.gz |
Merge pull request #96617 from RandomShaper/res_loader_pending
ResourceLoader: Add last resort life-time insurance for tokens
-rw-r--r-- | core/io/resource_loader.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 4201bfe785..f29f9eef98 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -319,6 +319,7 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin } // This implementation must allow re-entrancy for a task that started awaiting in a deeper stack frame. +// The load task token must be manually re-referenced before this is called, which includes threaded runs. void ResourceLoader::_run_load_task(void *p_userdata) { ThreadLoadTask &load_task = *(ThreadLoadTask *)p_userdata; @@ -449,6 +450,9 @@ void ResourceLoader::_run_load_task(void *p_userdata) { } } + // It's safe now to let the task go in case no one else was grabbing the token. + load_task.load_token->unreference(); + if (unlock_pending) { thread_load_mutex.unlock(); } @@ -599,6 +603,11 @@ Ref<ResourceLoader::LoadToken> ResourceLoader::_load_start(const String &p_path, } } + // It's important to keep the token alive because until the load completes, + // which includes before the thread start, it may happen that no one is grabbing + // the token anymore so it's released. + load_task_ptr->load_token->reference(); + if (p_thread_mode == LOAD_THREAD_FROM_CURRENT) { // The current thread may happen to be a thread from the pool. WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->get_caller_task_id(); @@ -783,6 +792,7 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro // 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. + load_task.load_token->reference(); _run_load_task(&load_task); } |