diff --git a/Source/DiabloUI/art.cpp b/Source/DiabloUI/art.cpp index 42b3b10a4..359648580 100644 --- a/Source/DiabloUI/art.cpp +++ b/Source/DiabloUI/art.cpp @@ -116,7 +116,7 @@ void LoadArt(const char *pszFile, Art *art, int frames, SDL_Color *pPalette) if (!LoadPcxMeta(handle, width, height, bpp)) { Log("LoadArt(\"{}\"): LoadPcxMeta failed with code {}", pszFile, SErrGetLastError()); - SFileCloseFile(handle); + SFileCloseFileThreadSafe(handle); return; } @@ -124,10 +124,10 @@ void LoadArt(const char *pszFile, Art *art, int frames, SDL_Color *pPalette) if (!LoadPcxPixelsAndPalette(handle, width, height, bpp, static_cast(artSurface->pixels), artSurface->pitch, pPalette)) { Log("LoadArt(\"{}\"): LoadPcxPixelsAndPalette failed with code {}", pszFile, SErrGetLastError()); - SFileCloseFile(handle); + SFileCloseFileThreadSafe(handle); return; } - SFileCloseFile(handle); + SFileCloseFileThreadSafe(handle); art->logical_width = artSurface->w; art->frame_height = height / frames; diff --git a/Source/engine.cpp b/Source/engine.cpp index ccd3bf5f8..9a9e050d9 100644 --- a/Source/engine.cpp +++ b/Source/engine.cpp @@ -230,7 +230,7 @@ size_t GetFileSize(const char *pszName) HANDLE file; SFileOpenFile(pszName, &file); const size_t fileLen = SFileGetFileSize(file, nullptr); - SFileCloseFile(file); + SFileCloseFileThreadSafe(file); return fileLen; } @@ -244,7 +244,7 @@ void LoadFileData(const char *pszName, byte *buffer, size_t fileLen) app_fatal("Zero length SFILE:\n%s", pszName); SFileReadFileThreadSafe(file, buffer, fileLen); - SFileCloseFile(file); + SFileCloseFileThreadSafe(file); } /** diff --git a/Source/init.cpp b/Source/init.cpp index f4ea29cd9..a845261dd 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -177,7 +177,7 @@ void init_archives() HANDLE fh = nullptr; if (!SFileOpenFile("ui_art\\title.pcx", &fh)) InsertCDDlg(); - SFileCloseFile(fh); + SFileCloseFileThreadSafe(fh); patch_rt_mpq = init_test_access(paths, "patch_rt.mpq"); if (patch_rt_mpq == nullptr) diff --git a/Source/pfile.cpp b/Source/pfile.cpp index 13005b5d3..4a4d4eaf0 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -147,7 +147,7 @@ static std::unique_ptr pfile_read_archive(HANDLE archive, const char std::unique_ptr buf { new uint8_t[*pdwLen] }; if (!SFileReadFileThreadSafe(file, buf.get(), *pdwLen, &nread)) return nullptr; - SFileCloseFile(file); + SFileCloseFileThreadSafe(file); *pdwLen = codec_decode(buf.get(), *pdwLen, pfile_get_password()); if (*pdwLen == 0) diff --git a/Source/player.cpp b/Source/player.cpp index 014987995..6c054be20 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -538,7 +538,7 @@ static DWORD GetPlrGFXSize(HeroClass c, const char *szCel) if (SFileOpenFile(pszName, &hsFile)) { assert(hsFile); dwSize = SFileGetFileSize(hsFile, nullptr); - SFileCloseFile(hsFile); + SFileCloseFileThreadSafe(hsFile); if (dwMaxSize <= dwSize) { dwMaxSize = dwSize; } diff --git a/Source/sound.cpp b/Source/sound.cpp index 815131a26..28cc53e19 100644 --- a/Source/sound.cpp +++ b/Source/sound.cpp @@ -48,7 +48,7 @@ void LoadMusic(HANDLE handle) int bytestoread = SFileGetFileSize(handle, 0); musicBuffer = new char[bytestoread]; SFileReadFileThreadSafe(handle, musicBuffer, bytestoread); - SFileCloseFile(handle); + SFileCloseFileThreadSafe(handle); SDL_RWops *musicRw = SDL_RWFromConstMem(musicBuffer, bytestoread); #endif @@ -178,7 +178,7 @@ std::unique_ptr sound_file_load(const char *path, bool stream) auto wave_file = MakeArraySharedPtr(dwBytes); SFileReadFileThreadSafe(file, wave_file.get(), dwBytes); error = snd->DSB.SetChunk(wave_file, dwBytes); - SFileCloseFile(file); + SFileCloseFileThreadSafe(file); } if (error != 0) { ErrSdl(); diff --git a/Source/storm/storm.cpp b/Source/storm/storm.cpp index 48bd0ab96..4406c42e7 100644 --- a/Source/storm/storm.cpp +++ b/Source/storm/storm.cpp @@ -35,13 +35,20 @@ std::string *SBasePath = nullptr; } // namespace +SDL_mutex *Mutex = SDL_CreateMutex(); + bool SFileReadFileThreadSafe(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, int *lpDistanceToMoveHigh) { - static SDL_mutex *Mutex = SDL_CreateMutex(); SDLMutexLockGuard lock(Mutex); return SFileReadFile(hFile, buffer, nNumberOfBytesToRead, read, lpDistanceToMoveHigh); } +bool SFileCloseFileThreadSafe(HANDLE hFile) +{ + SDLMutexLockGuard lock(Mutex); + return SFileCloseFile(hFile); +} + radon::File &getIni() { static radon::File ini(paths::ConfigPath() + "diablo.ini"); diff --git a/Source/storm/storm.h b/Source/storm/storm.h index b86883338..eabb56b20 100644 --- a/Source/storm/storm.h +++ b/Source/storm/storm.h @@ -321,9 +321,10 @@ bool SFileEnableDirectAccess(bool enable); // Additions to Storm API: -// Locks ReadFile under a mutex. +// Locks ReadFile and CloseFile under a mutex. // See https://github.com/ladislav-zezula/StormLib/issues/175 bool SFileReadFileThreadSafe(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read = nullptr, int *lpDistanceToMoveHigh = nullptr); +bool SFileCloseFileThreadSafe(HANDLE hFile); // Sets the file's 64-bit seek position. inline std::uint64_t SFileSetFilePointer(HANDLE hFile, std::int64_t offset, int whence) diff --git a/Source/storm/storm_file_wrapper.cpp b/Source/storm/storm_file_wrapper.cpp index ba1d470e9..e2f124671 100644 --- a/Source/storm/storm_file_wrapper.cpp +++ b/Source/storm/storm_file_wrapper.cpp @@ -49,7 +49,7 @@ int SFileCookieSeek(void *cookie, off64_t *pos, int whence) int SFileCookieClose(void *cookie) { - return SFileCloseFile(static_cast(cookie)) ? 0 : -1; + return SFileCloseFileThreadSafe(static_cast(cookie)) ? 0 : -1; } } // extern "C" diff --git a/Source/storm/storm_sdl_rw.cpp b/Source/storm/storm_sdl_rw.cpp index 43e42df68..a930250ad 100644 --- a/Source/storm/storm_sdl_rw.cpp +++ b/Source/storm/storm_sdl_rw.cpp @@ -71,7 +71,7 @@ static int SFileRwRead(struct SDL_RWops *context, void *ptr, int size, int maxnu static int SFileRwClose(struct SDL_RWops *context) { - SFileCloseFile(SFileRwGetHandle(context)); + SFileCloseFileThreadSafe(SFileRwGetHandle(context)); delete context; return 0; } diff --git a/Source/storm/storm_svid.cpp b/Source/storm/storm_svid.cpp index d4b93741e..3bbe96e9d 100644 --- a/Source/storm/storm_svid.cpp +++ b/Source/storm/storm_svid.cpp @@ -158,7 +158,7 @@ bool SVidPlayBegin(const char *filename, int flags, HANDLE *video) int bytestoread = SFileGetFileSize(*video, nullptr); SVidBuffer = std::unique_ptr { new uint8_t[bytestoread] }; SFileReadFileThreadSafe(*video, SVidBuffer.get(), bytestoread); - SFileCloseFile(*video); + SFileCloseFileThreadSafe(*video); *video = nullptr; SVidSMK = smk_open_memory(SVidBuffer.get(), bytestoread); #endif