Skip to content

Commit 789af64

Browse files
authored
bugfix(filesystem): Tentatively fix hang in file exist cache (#1751)
1 parent af4c40b commit 789af64

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

Core/GameEngine/Include/Common/FileSystem.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353

5454
#include <Utility/hash_map_adapter.h>
5555

56+
#include "mutex.h"
57+
5658
//----------------------------------------------------------------------------
5759
// Forward References
5860
//----------------------------------------------------------------------------
@@ -128,6 +130,10 @@ struct FileInfo {
128130
// TheSuperHackers @feature xezon 23/08/2025 Implements file instance access.
129131
// Can be used to access different versions of files in different archives under the same name.
130132
// Instance 0 refers to the top file that shadows all other files under the same name.
133+
//
134+
// TheSuperHackers @bugfix xezon 26/10/2025 Adds a mutex to the file exist map to try prevent
135+
// application hangs during level load after the file exist map was corrupted because of writes
136+
// from multiple threads.
131137
//===============================
132138
class FileSystem : public SubsystemInterface
133139
{
@@ -168,7 +174,9 @@ class FileSystem : public SubsystemInterface
168174
rts::string_key<AsciiString>, FileExistData,
169175
rts::string_key_hash<AsciiString>,
170176
rts::string_key_equal<AsciiString> > FileExistMap;
177+
171178
mutable FileExistMap m_fileExist;
179+
mutable FastCriticalSectionClass m_fileExistMutex;
172180
#endif
173181
};
174182

Core/GameEngine/Source/Common/System/FileSystem.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ File* FileSystem::openFile( const Char *filename, Int access, size_t bufferSize
192192
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
193193
if (file != NULL && (file->getAccess() & File::CREATE))
194194
{
195+
FastCriticalSectionClass::LockClass lock(m_fileExistMutex);
195196
FileExistMap::iterator it = m_fileExist.find(FileExistMap::key_type::temporary(filename));
196197
if (it != m_fileExist.end())
197198
{
@@ -227,6 +228,7 @@ Bool FileSystem::doesFileExist(const Char *filename, FileInstance instance) cons
227228

228229
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
229230
{
231+
FastCriticalSectionClass::LockClass lock(m_fileExistMutex);
230232
FileExistMap::const_iterator it = m_fileExist.find(FileExistMap::key_type::temporary(filename));
231233
if (it != m_fileExist.end())
232234
{
@@ -244,7 +246,10 @@ Bool FileSystem::doesFileExist(const Char *filename, FileInstance instance) cons
244246
if (instance == 0)
245247
{
246248
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
247-
m_fileExist[filename];
249+
{
250+
FastCriticalSectionClass::LockClass lock(m_fileExistMutex);
251+
m_fileExist[filename];
252+
}
248253
#endif
249254
return TRUE;
250255
}
@@ -255,15 +260,21 @@ Bool FileSystem::doesFileExist(const Char *filename, FileInstance instance) cons
255260
if (TheArchiveFileSystem->doesFileExist(filename, instance))
256261
{
257262
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
258-
FileExistMap::mapped_type& value = m_fileExist[filename];
259-
value.instanceExists = max(value.instanceExists, instance);
263+
{
264+
FastCriticalSectionClass::LockClass lock(m_fileExistMutex);
265+
FileExistMap::mapped_type& value = m_fileExist[filename];
266+
value.instanceExists = max(value.instanceExists, instance);
267+
}
260268
#endif
261269
return TRUE;
262270
}
263271

264272
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
265-
FileExistMap::mapped_type& value = m_fileExist[filename];
266-
value.instanceDoesNotExist = min(value.instanceDoesNotExist, instance);
273+
{
274+
FastCriticalSectionClass::LockClass lock(m_fileExistMutex);
275+
FileExistMap::mapped_type& value = m_fileExist[filename];
276+
value.instanceDoesNotExist = min(value.instanceDoesNotExist, instance);
277+
}
267278
#endif
268279
return FALSE;
269280
}

0 commit comments

Comments
 (0)