diff --git a/src/common/filesystem/include/resourcefile.h b/src/common/filesystem/include/resourcefile.h index 7709822e11..7dea3304bb 100644 --- a/src/common/filesystem/include/resourcefile.h +++ b/src/common/filesystem/include/resourcefile.h @@ -107,6 +107,8 @@ struct FResourceEntry int16_t Namespace; }; +void SetMainThread(); + class FResourceFile { public: diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index 86029186e1..e2be0b1870 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -245,6 +245,8 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil { int numfiles; + // the first call here will designate a main thread which may use shared file readers. All other thewads have to open new file handles. + SetMainThread(); // open all the files, load headers, and count lumps DeleteAll(); numfiles = 0; diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index 3a64cf13b6..1933c59aae 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -45,6 +45,18 @@ namespace FileSys { +// this is for restricting shared file readers to the main thread. +thread_local bool mainThread; +void SetMainThread() +{ + // only set the global flag on the first thread calling this. + static bool done = false; + if (!done) + { + mainThread = done = true; + } +} + std::string ExtractBaseName(const char* path, bool include_extension) { const char* src, * dot; @@ -553,6 +565,8 @@ FileReader FResourceFile::GetEntryReader(uint32_t entry, int readertype, int rea } if (!(Entries[entry].Flags & RESFF_COMPRESSED)) { + if (readertype == READER_SHARED && mainThread) + readertype = READER_NEW; if (readertype == READER_SHARED) { fr.OpenFilePart(Reader, Entries[entry].Position, Entries[entry].Length); @@ -571,7 +585,7 @@ FileReader FResourceFile::GetEntryReader(uint32_t entry, int readertype, int rea else { FileReader fri; - if (readertype == READER_NEW) fri.OpenFile(FileName, Entries[entry].Position, Entries[entry].CompressedSize); + if (readertype == READER_NEW || !mainThread) fri.OpenFile(FileName, Entries[entry].Position, Entries[entry].CompressedSize); else fri.OpenFilePart(Reader, Entries[entry].Position, Entries[entry].CompressedSize); int flags = DCF_TRANSFEROWNER | DCF_EXCEPTIONS; if (readertype == READER_CACHED) flags |= DCF_CACHED;