Make resource loader cycle checker work on a per-thread basis.
This removes editor errors saying cycles existed when the thumbnailer was running.
This commit is contained in:
parent
0a563bfab1
commit
1f9c54bd55
2 changed files with 51 additions and 9 deletions
|
@ -55,7 +55,7 @@ Error ResourceInteractiveLoader::wait() {
|
||||||
|
|
||||||
ResourceInteractiveLoader::~ResourceInteractiveLoader() {
|
ResourceInteractiveLoader::~ResourceInteractiveLoader() {
|
||||||
if (path_loading != String()) {
|
if (path_loading != String()) {
|
||||||
ResourceLoader::_remove_from_loading_map(path_loading);
|
ResourceLoader::_remove_from_loading_map_and_thread(path_loading, path_loading_thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,10 +293,14 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) {
|
||||||
loading_map_mutex->lock();
|
loading_map_mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading_map.has(p_path)) {
|
LoadingMapKey key;
|
||||||
|
key.path = p_path;
|
||||||
|
key.thread = Thread::get_caller_id();
|
||||||
|
|
||||||
|
if (loading_map.has(key)) {
|
||||||
success = false;
|
success = false;
|
||||||
} else {
|
} else {
|
||||||
loading_map[p_path] = true;
|
loading_map[key] = true;
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +316,27 @@ void ResourceLoader::_remove_from_loading_map(const String &p_path) {
|
||||||
loading_map_mutex->lock();
|
loading_map_mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
loading_map.erase(p_path);
|
LoadingMapKey key;
|
||||||
|
key.path = p_path;
|
||||||
|
key.thread = Thread::get_caller_id();
|
||||||
|
|
||||||
|
loading_map.erase(key);
|
||||||
|
|
||||||
|
if (loading_map_mutex) {
|
||||||
|
loading_map_mutex->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
|
||||||
|
if (loading_map_mutex) {
|
||||||
|
loading_map_mutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadingMapKey key;
|
||||||
|
key.path = p_path;
|
||||||
|
key.thread = p_thread;
|
||||||
|
|
||||||
|
loading_map.erase(key);
|
||||||
|
|
||||||
if (loading_map_mutex) {
|
if (loading_map_mutex) {
|
||||||
loading_map_mutex->unlock();
|
loading_map_mutex->unlock();
|
||||||
|
@ -471,6 +495,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
||||||
|
|
||||||
ril->resource = res_cached;
|
ril->resource = res_cached;
|
||||||
ril->path_loading = local_path;
|
ril->path_loading = local_path;
|
||||||
|
ril->path_loading_thread = Thread::get_caller_id();
|
||||||
return ril;
|
return ril;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,6 +524,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
||||||
if (!p_no_cache) {
|
if (!p_no_cache) {
|
||||||
ril->set_local_path(local_path);
|
ril->set_local_path(local_path);
|
||||||
ril->path_loading = local_path;
|
ril->path_loading = local_path;
|
||||||
|
ril->path_loading_thread = Thread::get_caller_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xl_remapped)
|
if (xl_remapped)
|
||||||
|
@ -919,7 +945,7 @@ void ResourceLoader::remove_custom_loaders() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex *ResourceLoader::loading_map_mutex = NULL;
|
Mutex *ResourceLoader::loading_map_mutex = NULL;
|
||||||
HashMap<String, int> ResourceLoader::loading_map;
|
HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
|
||||||
|
|
||||||
void ResourceLoader::initialize() {
|
void ResourceLoader::initialize() {
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
|
@ -929,9 +955,9 @@ void ResourceLoader::initialize() {
|
||||||
|
|
||||||
void ResourceLoader::finalize() {
|
void ResourceLoader::finalize() {
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
const String *K = NULL;
|
const LoadingMapKey *K = NULL;
|
||||||
while ((K = loading_map.next(K))) {
|
while ((K = loading_map.next(K))) {
|
||||||
ERR_PRINTS("Exited while resource is being loaded: " + *K);
|
ERR_PRINTS("Exited while resource is being loaded: " + K->path);
|
||||||
}
|
}
|
||||||
loading_map.clear();
|
loading_map.clear();
|
||||||
memdelete(loading_map_mutex);
|
memdelete(loading_map_mutex);
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#ifndef RESOURCE_LOADER_H
|
#ifndef RESOURCE_LOADER_H
|
||||||
#define RESOURCE_LOADER_H
|
#define RESOURCE_LOADER_H
|
||||||
|
|
||||||
|
#include "core/os/thread.h"
|
||||||
#include "core/resource.h"
|
#include "core/resource.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -42,6 +42,7 @@ class ResourceInteractiveLoader : public Reference {
|
||||||
GDCLASS(ResourceInteractiveLoader, Reference);
|
GDCLASS(ResourceInteractiveLoader, Reference);
|
||||||
friend class ResourceLoader;
|
friend class ResourceLoader;
|
||||||
String path_loading;
|
String path_loading;
|
||||||
|
Thread::ID path_loading_thread;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -121,10 +122,25 @@ class ResourceLoader {
|
||||||
|
|
||||||
static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
|
static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
|
||||||
static Mutex *loading_map_mutex;
|
static Mutex *loading_map_mutex;
|
||||||
static HashMap<String, int> loading_map;
|
|
||||||
|
//used to track paths being loaded in a thread, avoids cyclic recursion
|
||||||
|
struct LoadingMapKey {
|
||||||
|
String path;
|
||||||
|
Thread::ID thread;
|
||||||
|
bool operator==(const LoadingMapKey &p_key) const {
|
||||||
|
return (thread == p_key.thread && path == p_key.path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct LoadingMapKeyHasher {
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ uint32_t hash(const LoadingMapKey &p_key) { return p_key.path.hash() + HashMapHasherDefault::hash(p_key.thread); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static HashMap<LoadingMapKey, int, LoadingMapKeyHasher> loading_map;
|
||||||
|
|
||||||
static bool _add_to_loading_map(const String &p_path);
|
static bool _add_to_loading_map(const String &p_path);
|
||||||
static void _remove_from_loading_map(const String &p_path);
|
static void _remove_from_loading_map(const String &p_path);
|
||||||
|
static void _remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
|
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
|
||||||
|
|
Loading…
Reference in a new issue