refs #884 Protect filesystem race in settings using QLockFile.

This commit is contained in:
Mathew Sutcliffe
2017-03-15 18:36:45 +00:00
parent 0d0e2cf9e0
commit 70520d44c3
3 changed files with 42 additions and 3 deletions

View File

@@ -30,13 +30,41 @@ namespace BlackMisc
return dir;
}
const QString &CSettingsCache::lockFileName()
{
static const QString file = CFileUtils::appendFilePaths(persistentStore(), ".lock");
return file;
}
CStatusMessage CSettingsCache::lockFile(QLockFile &lock)
{
Q_ASSERT(!lock.isLocked());
if (!QDir::root().mkpath(persistentStore()))
{
return CStatusMessage(this).error("Failed to create %1") << persistentStore();
}
if (!lock.lock())
{
return CStatusMessage(this).error("Failed to lock %1: %2") << lockFileName() << CFileUtils::lockFileError(lock);
}
return {};
}
BlackMisc::CStatusMessage CSettingsCache::saveToStore(const QString &keyPrefix)
{
QLockFile lock(lockFileName());
const CStatusMessage lockStatus = lockFile(lock);
if (lockStatus.isFailure()) { return lockStatus; }
return saveToFiles(persistentStore(), keyPrefix);
}
BlackMisc::CStatusMessage CSettingsCache::saveToStore(const QStringList &keys)
{
QLockFile lock(lockFileName());
const CStatusMessage lockStatus = lockFile(lock);
if (lockStatus.isFailure()) { return lockStatus; }
return saveToFiles(persistentStore(), keys);
}
@@ -47,12 +75,24 @@ namespace BlackMisc
void CSettingsCache::saveToStoreByPacket(const CValueCachePacket &values)
{
QLockFile lock(lockFileName());
const CStatusMessage lockStatus = lockFile(lock);
if (lockStatus.isFailure())
{
CLogMessage::preformatted(lockStatus);
return;
}
CStatusMessage status = saveToFiles(persistentStore(), values.toVariantMap());
CLogMessage::preformatted(status);
}
BlackMisc::CStatusMessage CSettingsCache::loadFromStore()
{
QLockFile lock(lockFileName());
const CStatusMessage lockStatus = lockFile(lock);
if (lockStatus.isFailure()) { return lockStatus; }
return loadFromFiles(persistentStore());
}

View File

@@ -62,6 +62,8 @@ namespace BlackMisc
private:
CSettingsCache();
void saveToStoreByPacket(const CValueCachePacket &values);
static const QString &lockFileName();
CStatusMessage lockFile(QLockFile &);
};
/*!