281bool QLockFile::tryLock(std::chrono::milliseconds timeout)
283 using namespace std::chrono_literals;
284 using Msec = std::chrono::milliseconds;
288 QDeadlineTimer timer(timeout < 0ms ? Msec::max() : timeout);
290 Msec sleepTime = 100ms;
292 d->lockError = d->tryLock_sys();
293 switch (d->lockError) {
297 case PermissionError:
300 case LockFailedError:
301 if (!d->isLocked && d->isApparentlyStale()) {
302 if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified(QTimeZone::UTC) > QDateTime::currentDateTimeUtc()))
303 qInfo(
"QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName));
306 QLockFile rmlock(d->fileName +
".rmlock"_L1);
307 if (rmlock.tryLock()) {
308 if (d->isApparentlyStale() && d->removeStaleLock())
315 auto remainingTime = std::chrono::duration_cast<Msec>(timer.remainingTimeAsDuration());
316 if (remainingTime == 0ms)
319 if (sleepTime > remainingTime)
320 sleepTime = remainingTime;
322 QThread::sleep(sleepTime);
364bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname)
const
366 Q_D(
const QLockFile);
368 if (!getLockInfo_helper(d->fileName, &info))
373 *hostname = info.hostname;
375 *appname = info.appname;
404 QFile reader(fileName);
405 if (!reader.open(QIODevice::ReadOnly | QIODevice::Text))
408 QByteArray pidLine = reader.readLine();
410 if (pidLine.isEmpty())
412 QByteArray appNameLine = reader.readLine();
414 QByteArray hostNameLine = reader.readLine();
415 hostNameLine.chop(1);
418 QByteArray hostId = reader.readLine();
420 QByteArray bootId = reader.readLine();
424 info->appname = QString::fromUtf8(appNameLine);
425 info->hostname = QString::fromUtf8(hostNameLine);
426 info->hostid = hostId;
427 info->bootid = bootId;
428 info->pid = pidLine.toLongLong(&ok);
429 return ok && info->pid > 0;
435 if (getLockInfo_helper(fileName, &info)) {
436 bool sameHost = info.hostname.isEmpty() || info.hostname == machineName();
437 if (!info.hostid.isEmpty()) {
439 QByteArray ourHostId = QSysInfo::machineUniqueId();
440 if (!ourHostId.isEmpty())
441 sameHost = (ourHostId == info.hostid);
445 if (!info.bootid.isEmpty()) {
447 if (info.bootid != QSysInfo::bootUniqueId())
450 if (!isProcessRunning(info.pid, info.appname))
455 const QDateTime lastMod = QFileInfo(fileName).lastModified(QTimeZone::UTC);
456 using namespace std::chrono;
457 const milliseconds age{lastMod.msecsTo(QDateTime::currentDateTimeUtc())};
458 return staleLockTime > 0ms && abs(age) > staleLockTime;