Fix crash in Content Storage async job when someone is using file storage and access cannot be freed

This commit is contained in:
Wojtek Figat
2023-12-07 11:18:18 +01:00
parent d847dfda61
commit 3749b35aba
3 changed files with 20 additions and 6 deletions

View File

@@ -729,7 +729,11 @@ bool FlaxStorage::ChangeAssetID(Entry& e, const Guid& newId)
} }
// Close file // Close file
CloseFileHandles(); if (CloseFileHandles())
{
LOG(Error, "Cannot close file access for '{}'", _path);
return true;
}
// Change ID // Change ID
// TODO: here we could extend it and load assets from the storage and call asset ID change event to change references // 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; 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 // 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 // In those situations all the async tasks using this storage should be cancelled externally
@@ -1326,10 +1330,12 @@ void FlaxStorage::CloseFileHandles()
waitTime = 100; waitTime = 100;
while (Platform::AtomicRead(&_chunksLock) != 0 && waitTime-- > 0) while (Platform::AtomicRead(&_chunksLock) != 0 && waitTime-- > 0)
Platform::Sleep(1); 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) // Close file handles (from all threads)
_file.DeleteAll(); _file.DeleteAll();
return false;
} }
void FlaxStorage::Dispose() void FlaxStorage::Dispose()
@@ -1338,7 +1344,10 @@ void FlaxStorage::Dispose()
return; return;
// Close file // Close file
CloseFileHandles(); if (CloseFileHandles())
{
LOG(Error, "Cannot close file access for '{}'", _path);
}
// Release data // Release data
_chunks.ClearDelete(); _chunks.ClearDelete();

View File

@@ -405,7 +405,7 @@ public:
/// <summary> /// <summary>
/// Closes the file handles (it can be modified from the outside). /// Closes the file handles (it can be modified from the outside).
/// </summary> /// </summary>
void CloseFileHandles(); bool CloseFileHandles();
/// <summary> /// <summary>
/// Releases storage resources and closes handle to the file. /// Releases storage resources and closes handle to the file.

View File

@@ -176,7 +176,12 @@ void CreateAssetContext::ApplyChanges()
auto storage = ContentStorageManager::TryGetStorage(TargetAssetPath); auto storage = ContentStorageManager::TryGetStorage(TargetAssetPath);
if (storage && storage->IsLoaded()) if (storage && storage->IsLoaded())
{ {
storage->CloseFileHandles(); if (storage->CloseFileHandles())
{
LOG(Error, "Cannot close file access for '{}'", TargetAssetPath);
_applyChangesResult = CreateAssetResult::CannotSaveFile;
return;
}
} }
// Move file // Move file