2
0
Эх сурвалжийг харах

Change ResourceLoader::load to make it more thread safe.

Juan Linietsky 7 жил өмнө
parent
commit
19d57894d8

+ 25 - 5
core/io/resource_loader.cpp

@@ -202,12 +202,32 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
 	else
 		local_path = ProjectSettings::get_singleton()->localize_path(p_path);
 
-	if (!p_no_cache && ResourceCache::has(local_path)) {
+	if (!p_no_cache) {
+		//lock first if possible
+		if (ResourceCache::lock) {
+			ResourceCache::lock->read_lock();
+		}
 
-		print_verbose("Loading resource: " + local_path + " (cached)");
-		if (r_error)
-			*r_error = OK;
-		return RES(ResourceCache::get(local_path));
+		//get ptr
+		Resource **rptr = ResourceCache::resources.getptr(local_path);
+
+		if (rptr) {
+			RES res(*rptr);
+			//it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
+			if (res.is_valid()) {
+				//referencing is fine
+				if (r_error)
+					*r_error = OK;
+				if (ResourceCache::lock) {
+					ResourceCache::lock->read_unlock();
+				}
+				print_verbose("Loading resource: " + local_path + " (cached)");
+				return res;
+			}
+		}
+		if (ResourceCache::lock) {
+			ResourceCache::lock->read_unlock();
+		}
 	}
 
 	bool xl_remapped = false;