Update ReArchive.cpp
busy-wait in the event of a thread collision.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#include <ReArchive/ReArchive.h>
|
||||
|
||||
#include <unordered_set>
|
||||
#include <ReArchive/types/Header.h>
|
||||
#include <ReArchive/types/FileTable.h>
|
||||
#include <ReArchive/types/FileEntry.h>
|
||||
@@ -9,6 +9,8 @@ using ReArchive::Header;
|
||||
using ReArchive::FileTable;
|
||||
using ReArchive::FileEntry;
|
||||
|
||||
std::unordered_set<std::filesystem::path> locked {};
|
||||
|
||||
Header GetHeader(const unsigned char* archive) {
|
||||
ReArchive::Header h = ReArchive::Header::DeSerialize(archive);
|
||||
return h;
|
||||
@@ -72,6 +74,11 @@ bool ReArchive::CreateArchive(const std::filesystem::path& filesystem_path, bool
|
||||
if (std::filesystem::exists(filesystem_path))
|
||||
return false;
|
||||
|
||||
if (locked.contains(filesystem_path))
|
||||
return false;
|
||||
|
||||
locked.insert(filesystem_path);
|
||||
|
||||
std::ofstream file(filesystem_path, std::ios::binary);
|
||||
if (!file)
|
||||
return false;
|
||||
@@ -86,6 +93,12 @@ bool ReArchive::CreateArchive(const std::filesystem::path& filesystem_path, bool
|
||||
|
||||
if (running_tally)
|
||||
*running_tally = file_table;
|
||||
|
||||
// Remove lock.
|
||||
auto position = locked.find(filesystem_path);
|
||||
if (position != locked.end())
|
||||
locked.erase(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,6 +106,10 @@ bool ReArchive::WriteFile(const std::filesystem::path& archive, const std::files
|
||||
if (!std::filesystem::exists(archive))
|
||||
return false;
|
||||
|
||||
// Busy-wait.
|
||||
while (locked.contains(archive)) {}
|
||||
locked.insert(archive);
|
||||
|
||||
std::ifstream in(archive, std::ios::binary);
|
||||
if (!in)
|
||||
return false;
|
||||
@@ -133,8 +150,14 @@ bool ReArchive::WriteFile(const std::filesystem::path& archive, const std::files
|
||||
out.write(reinterpret_cast<const char *>(new_header.data()), (int64_t) new_header.size());
|
||||
out.close();
|
||||
|
||||
// Remove lock.
|
||||
auto position = locked.find(archive);
|
||||
if (position != locked.end())
|
||||
locked.erase(position);
|
||||
|
||||
if (running_tally)
|
||||
*running_tally = file_table;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,6 +165,10 @@ bool ReArchive::OverwriteFile(const std::filesystem::path& archive, const std::f
|
||||
if (!std::filesystem::exists(archive))
|
||||
return false;
|
||||
|
||||
// Busy-wait.
|
||||
while (locked.contains(archive)) {}
|
||||
locked.insert(archive);
|
||||
|
||||
std::ifstream in(archive, std::ios::binary);
|
||||
if (!in)
|
||||
return false;
|
||||
@@ -179,6 +206,11 @@ bool ReArchive::OverwriteFile(const std::filesystem::path& archive, const std::f
|
||||
out.write(reinterpret_cast<const char *>(file_data), byte_count);
|
||||
out.close();
|
||||
|
||||
// Remove lock.
|
||||
auto position = locked.find(archive);
|
||||
if (position != locked.end())
|
||||
locked.erase(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -224,6 +256,10 @@ bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::files
|
||||
if (!std::filesystem::exists(archive))
|
||||
return false;
|
||||
|
||||
// Busy-wait.
|
||||
while (locked.contains(archive)) {}
|
||||
locked.insert(archive);
|
||||
|
||||
std::ifstream in(archive, std::ios::binary);
|
||||
if (!in)
|
||||
return false;
|
||||
@@ -266,5 +302,10 @@ bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::files
|
||||
if (running_tally)
|
||||
*running_tally = current_file_table;
|
||||
|
||||
// Remove lock.
|
||||
auto position = locked.find(archive);
|
||||
if (position != locked.end())
|
||||
locked.erase(position);
|
||||
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user