279bool QLockFile::tryLock(std::chrono::milliseconds timeout)
281 using namespace std::chrono_literals;
282 using Msec = std::chrono::milliseconds;
286 QDeadlineTimer timer(timeout < 0ms ? Msec::max() : timeout);
288 Msec sleepTime = 100ms;
290 d->lockError = d->tryLock_sys();
291 switch (d->lockError) {
295 case PermissionError:
298 case LockFailedError:
299 if (!d->isLocked && d->isApparentlyStale()) {
300 if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified(QTimeZone::UTC) > QDateTime::currentDateTimeUtc()))
301 qInfo(
"QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName));
304 QLockFile rmlock(d->fileName +
".rmlock"_L1);
305 if (rmlock.tryLock()) {
306 if (d->isApparentlyStale() && d->removeStaleLock())
313 auto remainingTime = std::chrono::duration_cast<Msec>(timer.remainingTimeAsDuration());
314 if (remainingTime == 0ms)
317 if (sleepTime > remainingTime)
318 sleepTime = remainingTime;
320 QThread::sleep(sleepTime);
362bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname)
const
364 Q_D(
const QLockFile);
366 if (!getLockInfo_helper(d->fileName, &info))
371 *hostname = info.hostname;
373 *appname = info.appname;
389 QFile reader(fileName);
390 if (!reader.open(QIODevice::ReadOnly | QIODevice::Text))
393 QByteArray pidLine = reader.readLine();
395 if (pidLine.isEmpty())
397 QByteArray appNameLine = reader.readLine();
399 QByteArray hostNameLine = reader.readLine();
400 hostNameLine.chop(1);
403 QByteArray hostId = reader.readLine();
405 QByteArray bootId = reader.readLine();
409 info->appname = QString::fromUtf8(appNameLine);
410 info->hostname = QString::fromUtf8(hostNameLine);
411 info->hostid = hostId;
412 info->bootid = bootId;
413 info->pid = pidLine.toLongLong(&ok);
414 return ok && info->pid > 0;
420 if (getLockInfo_helper(fileName, &info)) {
421 bool sameHost = info.hostname.isEmpty() || info.hostname == machineName();
422 if (!info.hostid.isEmpty()) {
424 QByteArray ourHostId = QSysInfo::machineUniqueId();
425 if (!ourHostId.isEmpty())
426 sameHost = (ourHostId == info.hostid);
430 if (!info.bootid.isEmpty()) {
432 if (info.bootid != QSysInfo::bootUniqueId())
435 if (!isProcessRunning(info.pid, info.appname))
440 const QDateTime lastMod = QFileInfo(fileName).lastModified(QTimeZone::UTC);
441 using namespace std::chrono;
442 const milliseconds age{lastMod.msecsTo(QDateTime::currentDateTimeUtc())};
443 return staleLockTime > 0ms && abs(age) > staleLockTime;