forked from quickshell/quickshell
tooling: add per-shell tooling lock to prevent races
This commit is contained in:
parent
986749cdb9
commit
78e3874ac6
2 changed files with 41 additions and 0 deletions
|
@ -1,5 +1,7 @@
|
|||
#include "toolsupport.hpp"
|
||||
#include <cerrno>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qdebug.h>
|
||||
#include <qdir.h>
|
||||
|
@ -28,6 +30,10 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!QmlToolingSupport::lockTooling()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!QmlToolingSupport::updateQmllsConfig(configRoot, false)) {
|
||||
QDir(vfs->filePath("qs")).removeRecursively();
|
||||
return false;
|
||||
|
@ -37,6 +43,39 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QmlToolingSupport::lockTooling() {
|
||||
if (QmlToolingSupport::toolingLock) return true;
|
||||
|
||||
auto lockPath = QsPaths::instance()->shellVfsDir()->filePath("tooling.lock");
|
||||
auto* file = new QFile(lockPath);
|
||||
|
||||
if (!file->open(QFile::WriteOnly)) {
|
||||
qCCritical(logTooling) << "Could not open tooling lock for write";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto lock = flock {
|
||||
.l_type = F_WRLCK,
|
||||
.l_whence = SEEK_SET, // NOLINT (fcntl.h??)
|
||||
.l_start = 0,
|
||||
.l_len = 0,
|
||||
.l_pid = 0,
|
||||
};
|
||||
|
||||
if (fcntl(file->handle(), F_SETLK, &lock) == 0) {
|
||||
qCInfo(logTooling) << "Acquired tooling support lock";
|
||||
QmlToolingSupport::toolingLock = file;
|
||||
return true;
|
||||
} else if (errno == EACCES || errno == EAGAIN) {
|
||||
qCInfo(logTooling) << "Tooling support locked by another instance";
|
||||
return false;
|
||||
} else {
|
||||
qCCritical(logTooling).nospace() << "Could not create tooling lock at " << lockPath
|
||||
<< " with error code " << errno << ": " << qt_error_string();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString QmlToolingSupport::getQmllsConfig() {
|
||||
static auto config = []() {
|
||||
QList<QString> importPaths;
|
||||
|
|
|
@ -12,9 +12,11 @@ public:
|
|||
|
||||
private:
|
||||
static QString getQmllsConfig();
|
||||
static bool lockTooling();
|
||||
static bool updateQmllsConfig(const QDir& configRoot, bool create);
|
||||
static void updateToolingFs(QmlScanner& scanner, const QDir& scanDir, const QDir& linkDir);
|
||||
static inline bool toolingEnabled = false;
|
||||
static inline QFile* toolingLock = nullptr;
|
||||
};
|
||||
|
||||
} // namespace qs::core
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue