11#include " toolsupport.hpp"
2+ #include < cerrno>
23
4+ #include < fcntl.h>
35#include < qcontainerfwd.h>
46#include < qdebug.h>
57#include < qdir.h>
@@ -28,6 +30,10 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
2830 return false ;
2931 }
3032
33+ if (!QmlToolingSupport::lockTooling ()) {
34+ return false ;
35+ }
36+
3137 if (!QmlToolingSupport::updateQmllsConfig (configRoot, false )) {
3238 QDir (vfs->filePath (" qs" )).removeRecursively ();
3339 return false ;
@@ -37,6 +43,39 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
3743 return true ;
3844}
3945
46+ bool QmlToolingSupport::lockTooling () {
47+ if (QmlToolingSupport::toolingLock) return true ;
48+
49+ auto lockPath = QsPaths::instance ()->shellVfsDir ()->filePath (" tooling.lock" );
50+ auto * file = new QFile (lockPath);
51+
52+ if (!file->open (QFile::WriteOnly)) {
53+ qCCritical (logTooling) << " Could not open tooling lock for write" ;
54+ return false ;
55+ }
56+
57+ auto lock = flock {
58+ .l_type = F_WRLCK,
59+ .l_whence = SEEK_SET, // NOLINT (fcntl.h??)
60+ .l_start = 0 ,
61+ .l_len = 0 ,
62+ .l_pid = 0 ,
63+ };
64+
65+ if (fcntl (file->handle (), F_SETLK, &lock) == 0 ) {
66+ qCInfo (logTooling) << " Acquired tooling support lock" ;
67+ QmlToolingSupport::toolingLock = file;
68+ return true ;
69+ } else if (errno == EACCES || errno == EAGAIN) {
70+ qCInfo (logTooling) << " Tooling support locked by another instance" ;
71+ return false ;
72+ } else {
73+ qCCritical (logTooling).nospace () << " Could not create tooling lock at " << lockPath
74+ << " with error code " << errno << " : " << qt_error_string ();
75+ return false ;
76+ }
77+ }
78+
4079QString QmlToolingSupport::getQmllsConfig () {
4180 static auto config = []() {
4281 QList<QString> importPaths;
0 commit comments