Fix asset load to trigger loading task within mutex to prevent race conditions when loading the same prefab from many threads at once

This commit is contained in:
Wojtek Figat
2023-10-16 16:10:57 +02:00
parent 036ad570cd
commit 50d47fe801
2 changed files with 6 additions and 8 deletions

View File

@@ -538,11 +538,7 @@ ContentLoadTask* Asset::createLoadingTask()
void Asset::startLoading() void Asset::startLoading()
{ {
// Check if is already loaded ASSERT(!IsLoaded());
if (IsLoaded())
return;
// Start loading (using async tasks)
ASSERT(_loadingTask == nullptr); ASSERT(_loadingTask == nullptr);
_loadingTask = createLoadingTask(); _loadingTask = createLoadingTask();
ASSERT(_loadingTask != nullptr); ASSERT(_loadingTask != nullptr);

View File

@@ -154,7 +154,7 @@ void ContentService::LateUpdate()
// Unload marked assets // Unload marked assets
for (int32 i = 0; i < ToUnload.Count(); i++) for (int32 i = 0; i < ToUnload.Count(); i++)
{ {
Asset* asset = ToUnload[i]; Asset* asset = ToUnload[i];
// Check if has no references // Check if has no references
if (asset->GetReferencesCount() <= 0) if (asset->GetReferencesCount() <= 0)
@@ -965,7 +965,7 @@ Asset* Content::load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo&
// Get cached asset info (from registry) // Get cached asset info (from registry)
if (!GetAssetInfo(id, assetInfo)) if (!GetAssetInfo(id, assetInfo))
{ {
LOG(Warning, "Invalid or missing asset ({0}, {1}).", id.ToString(Guid::FormatType::N), type.ToString()); LOG(Warning, "Invalid or missing asset ({0}, {1}).", id, type.ToString());
return nullptr; return nullptr;
} }
@@ -1009,11 +1009,13 @@ Asset* Content::load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo&
ASSERT(!Assets.ContainsKey(id)); ASSERT(!Assets.ContainsKey(id));
#endif #endif
Assets.Add(id, result); Assets.Add(id, result);
AssetsLocker.Unlock();
// Start asset loading // Start asset loading
// TODO: refactor this to create asset loading task-chain before AssetsLocker.Lock() to allow better parallelization
result->startLoading(); result->startLoading();
AssetsLocker.Unlock();
return result; return result;
} }