From 1f8645fd4342fe8fb22e1cec3c15fb980ae5bebf Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 17 Mar 2023 11:43:50 +0100 Subject: [PATCH] fix: Occasional crash when multiple threads are reading data from a file provider --- lib/libimhex/include/hex/api/content_registry.hpp | 2 +- lib/libimhex/include/hex/api/imhex_api.hpp | 2 +- .../builtin/include/content/providers/file_provider.hpp | 8 +++++--- .../builtin/source/content/providers/file_provider.cpp | 9 ++++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/libimhex/include/hex/api/content_registry.hpp b/lib/libimhex/include/hex/api/content_registry.hpp index 4f8449f6c..eeafaa522 100644 --- a/lib/libimhex/include/hex/api/content_registry.hpp +++ b/lib/libimhex/include/hex/api/content_registry.hpp @@ -385,7 +385,7 @@ namespace hex { namespace impl { - using Callback = std::function; + using Callback = std::function; struct Entry { std::vector extensions; Callback callback; diff --git a/lib/libimhex/include/hex/api/imhex_api.hpp b/lib/libimhex/include/hex/api/imhex_api.hpp index 59b91716a..30e8cd9e6 100644 --- a/lib/libimhex/include/hex/api/imhex_api.hpp +++ b/lib/libimhex/include/hex/api/imhex_api.hpp @@ -175,7 +175,7 @@ namespace hex { void setBorderlessWindowMode(bool enabled); - void setCustomFontPath(const std::filesystem::path &path); + void setCustomFontPath(const std::fs::path &path); void setFontSize(float size); void setGPUVendor(const std::string &vendor); diff --git a/plugins/builtin/include/content/providers/file_provider.hpp b/plugins/builtin/include/content/providers/file_provider.hpp index 17948e067..c27c39e2e 100644 --- a/plugins/builtin/include/content/providers/file_provider.hpp +++ b/plugins/builtin/include/content/providers/file_provider.hpp @@ -4,9 +4,9 @@ #include +#include #include - namespace hex::plugin::builtin { class FileProvider : public hex::prv::Provider { @@ -59,13 +59,15 @@ namespace hex::plugin::builtin { protected: std::fs::path m_path; + + wolv::io::File m_sizeFile; std::map m_files; - size_t m_fileSize = 0; std::optional m_fileStats; bool m_readable = false, m_writable = false; - bool m_openReadOnly = true; + + std::mutex m_fileAccessMutex, m_writeMutex; }; } \ No newline at end of file diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index bfb21ac66..7b89e51f7 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -71,6 +71,7 @@ namespace hex::plugin::builtin { if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0) return; + std::scoped_lock lock(this->m_writeMutex); wolv::io::File writeFile(this->m_path, wolv::io::File::Mode::Write); if (!writeFile.isValid()) return; @@ -140,7 +141,7 @@ namespace hex::plugin::builtin { } size_t FileProvider::getActualSize() const { - return this->m_fileSize; + return this->m_sizeFile.getSize(); } std::string FileProvider::getName() const { @@ -203,7 +204,7 @@ namespace hex::plugin::builtin { } this->m_fileStats = file.getFileInfo(); - this->m_fileSize = file.getSize(); + this->m_sizeFile = wolv::io::File(this->m_path, wolv::io::File::Mode::Read); return true; } @@ -213,6 +214,8 @@ namespace hex::plugin::builtin { } wolv::io::File& FileProvider::getFile() { + std::scoped_lock lock(this->m_fileAccessMutex); + if (this->m_files.size() > 5) this->m_files.clear(); @@ -229,7 +232,7 @@ namespace hex::plugin::builtin { std::fs::path path = std::u8string(pathString.begin(), pathString.end()); if (auto projectPath = ProjectFile::getPath(); !projectPath.empty()) - this->setPath(std::filesystem::weakly_canonical(projectPath.parent_path() / path)); + this->setPath(std::fs::weakly_canonical(projectPath.parent_path() / path)); else this->setPath(path); }