Merge pull request #14082 from Ondsel-Development/issue_13522_fix_read_lock

Core: Add read lock to fix for possible race conditions reading/writing config files
This commit is contained in:
Chris Hennes
2024-05-27 10:41:23 -05:00
committed by GitHub
5 changed files with 67 additions and 13 deletions

View File

@@ -1617,6 +1617,7 @@ ParameterManager::ParameterManager()
// ---------------------------------------------------------------------------
// NOLINTBEGIN
gIgnoreSave = false;
gDoNamespaces = false;
gDoSchema = false;
gSchemaFullChecking = false;
@@ -1723,14 +1724,28 @@ void ParameterManager::SaveDocument() const
}
}
void ParameterManager::SetIgnoreSave(bool value)
{
gIgnoreSave = value;
}
bool ParameterManager::IgnoreSave() const
{
return gIgnoreSave;
}
namespace
{
void waitForFileAccess(const Base::FileInfo& file)
QString getLockFile(const Base::FileInfo& file)
{
QFileInfo fi(QDir::tempPath(), QString::fromStdString(file.fileName() + ".lock"));
QLockFile lock(fi.absoluteFilePath());
const int waitOneSecond = 1000;
lock.tryLock(waitOneSecond);
return fi.absoluteFilePath();
}
int getTimeout()
{
const int timeout = 5000;
return timeout;
}
} // namespace
@@ -1753,7 +1768,14 @@ int ParameterManager::LoadDocument(const char* sFileName)
{
try {
Base::FileInfo file(sFileName);
waitForFileAccess(file);
QLockFile lock(getLockFile(file));
if (!lock.tryLock(getTimeout())) {
// Continue with empty config
CreateDocument();
SetIgnoreSave(true);
std::cerr << "Failed to access file for reading: " << sFileName << std::endl;
return 1;
}
#if defined(FC_OS_WIN32)
std::wstring name = file.toStdWString();
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
@@ -1845,7 +1867,11 @@ void ParameterManager::SaveDocument(const char* sFileName) const
{
try {
Base::FileInfo file(sFileName);
waitForFileAccess(file);
QLockFile lock(getLockFile(file));
if (!lock.tryLock(getTimeout())) {
std::cerr << "Failed to access file for writing: " << sFileName << std::endl;
return;
}
//
// Plug in a format target to receive the resultant
// XML stream from the serializer.

View File

@@ -434,12 +434,15 @@ public:
bool LoadOrCreateDocument();
/// Saves an XML document by calling the serializer's save method.
void SaveDocument() const;
void SetIgnoreSave(bool value);
bool IgnoreSave() const;
//@}
private:
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* _pDocument {nullptr};
ParameterSerializer* paramSerializer {nullptr};
bool gIgnoreSave;
bool gDoNamespaces;
bool gDoSchema;
bool gSchemaFullChecking;