From 3749b35aba18bf5c1331c154ec8bce6f09184dd3 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 7 Dec 2023 11:18:18 +0100 Subject: [PATCH] Fix crash in Content Storage async job when someone is using file storage and access cannot be freed --- Source/Engine/Content/Storage/FlaxStorage.cpp | 17 +++++++++++++---- Source/Engine/Content/Storage/FlaxStorage.h | 2 +- .../ContentImporters/AssetsImportingManager.cpp | 7 ++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Source/Engine/Content/Storage/FlaxStorage.cpp b/Source/Engine/Content/Storage/FlaxStorage.cpp index 77e91f0c4..b632fc6d3 100644 --- a/Source/Engine/Content/Storage/FlaxStorage.cpp +++ b/Source/Engine/Content/Storage/FlaxStorage.cpp @@ -729,7 +729,11 @@ bool FlaxStorage::ChangeAssetID(Entry& e, const Guid& newId) } // Close file - CloseFileHandles(); + if (CloseFileHandles()) + { + LOG(Error, "Cannot close file access for '{}'", _path); + return true; + } // Change ID // TODO: here we could extend it and load assets from the storage and call asset ID change event to change references @@ -1299,7 +1303,7 @@ FileReadStream* FlaxStorage::OpenFile() return stream; } -void FlaxStorage::CloseFileHandles() +bool FlaxStorage::CloseFileHandles() { // Note: this is usually called by the content manager when this file is not used or on exit // In those situations all the async tasks using this storage should be cancelled externally @@ -1326,10 +1330,12 @@ void FlaxStorage::CloseFileHandles() waitTime = 100; while (Platform::AtomicRead(&_chunksLock) != 0 && waitTime-- > 0) Platform::Sleep(1); - ASSERT(_chunksLock == 0); + if (Platform::AtomicRead(&_chunksLock) != 0) + return true; // Failed, someone is still accessing the file // Close file handles (from all threads) _file.DeleteAll(); + return false; } void FlaxStorage::Dispose() @@ -1338,7 +1344,10 @@ void FlaxStorage::Dispose() return; // Close file - CloseFileHandles(); + if (CloseFileHandles()) + { + LOG(Error, "Cannot close file access for '{}'", _path); + } // Release data _chunks.ClearDelete(); diff --git a/Source/Engine/Content/Storage/FlaxStorage.h b/Source/Engine/Content/Storage/FlaxStorage.h index 85c9db072..77c912c5a 100644 --- a/Source/Engine/Content/Storage/FlaxStorage.h +++ b/Source/Engine/Content/Storage/FlaxStorage.h @@ -405,7 +405,7 @@ public: /// /// Closes the file handles (it can be modified from the outside). /// - void CloseFileHandles(); + bool CloseFileHandles(); /// /// Releases storage resources and closes handle to the file. diff --git a/Source/Engine/ContentImporters/AssetsImportingManager.cpp b/Source/Engine/ContentImporters/AssetsImportingManager.cpp index bbefc687a..a0b28f4f8 100644 --- a/Source/Engine/ContentImporters/AssetsImportingManager.cpp +++ b/Source/Engine/ContentImporters/AssetsImportingManager.cpp @@ -176,7 +176,12 @@ void CreateAssetContext::ApplyChanges() auto storage = ContentStorageManager::TryGetStorage(TargetAssetPath); if (storage && storage->IsLoaded()) { - storage->CloseFileHandles(); + if (storage->CloseFileHandles()) + { + LOG(Error, "Cannot close file access for '{}'", TargetAssetPath); + _applyChangesResult = CreateAssetResult::CannotSaveFile; + return; + } } // Move file