1
1
#include " toolsupport.hpp"
2
+ #include < cerrno>
2
3
4
+ #include < fcntl.h>
3
5
#include < qcontainerfwd.h>
4
6
#include < qdebug.h>
5
7
#include < qdir.h>
@@ -28,6 +30,10 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
28
30
return false ;
29
31
}
30
32
33
+ if (!QmlToolingSupport::lockTooling ()) {
34
+ return false ;
35
+ }
36
+
31
37
if (!QmlToolingSupport::updateQmllsConfig (configRoot, false )) {
32
38
QDir (vfs->filePath (" qs" )).removeRecursively ();
33
39
return false ;
@@ -37,6 +43,39 @@ bool QmlToolingSupport::updateTooling(const QDir& configRoot, QmlScanner& scanne
37
43
return true ;
38
44
}
39
45
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
+
40
79
QString QmlToolingSupport::getQmllsConfig () {
41
80
static auto config = []() {
42
81
QList<QString> importPaths;
0 commit comments