diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 5a452226e00..1c061890a80 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -216,7 +216,7 @@ bool QLockFile::isLocked() const */ bool QLockFile::lock() { - return tryLock(-1); + return tryLock(std::chrono::milliseconds::max()); } /*! @@ -241,10 +241,42 @@ bool QLockFile::lock() */ bool QLockFile::tryLock(int timeout) { + return tryLock(std::chrono::milliseconds{ timeout }); +} + +/*! \fn bool QLockFile::tryLock(std::chrono::milliseconds timeout) + \overload + \since 6.2 + + Attempts to create the lock file. This function returns \c true if the + lock was obtained; otherwise it returns \c false. If another process (or + another thread) has created the lock file already, this function will + wait for at most \a timeout for the lock file to become available. + + If the lock was obtained, it must be released with unlock() + before another process (or thread) can successfully lock it. + + Calling this function multiple times on the same lock from the same + thread without unlocking first is not allowed, this function will + \e always return false when attempting to lock the file recursively. + + \sa lock(), unlock() +*/ +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +bool QLockFile::tryLock(std::chrono::milliseconds timeout) +#else +bool QLockFile::tryLock_impl(std::chrono::milliseconds timeout) +#endif +{ + using namespace std::chrono_literals; + using Msec = std::chrono::milliseconds; + Q_D(QLockFile); - QDeadlineTimer timer(qMax(timeout, -1)); // QDT only takes -1 as "forever" - int sleepTime = 100; - forever { + + QDeadlineTimer timer(timeout < 0ms ? Msec::max() : timeout); + + Msec sleepTime = 100ms; + while (true) { d->lockError = d->tryLock_sys(); switch (d->lockError) { case NoError: @@ -268,39 +300,21 @@ bool QLockFile::tryLock(int timeout) break; } - int remainingTime = timer.remainingTime(); - if (remainingTime == 0) + auto remainingTime = std::chrono::duration_cast(timer.remainingTimeAsDuration()); + if (remainingTime == 0ms) return false; - else if (uint(sleepTime) > uint(remainingTime)) + + if (sleepTime > remainingTime) sleepTime = remainingTime; - QThread::msleep(sleepTime); - if (sleepTime < 5 * 1000) + QThread::sleep(sleepTime); + if (sleepTime < 5s) sleepTime *= 2; } // not reached return false; } -/*! \fn bool QLockFile::tryLock(std::chrono::milliseconds timeout) - \overload - \since 6.2 - - Attempts to create the lock file. This function returns \c true if the - lock was obtained; otherwise it returns \c false. If another process (or - another thread) has created the lock file already, this function will - wait for at most \a timeout for the lock file to become available. - - If the lock was obtained, it must be released with unlock() - before another process (or thread) can successfully lock it. - - Calling this function multiple times on the same lock from the same - thread without unlocking first is not allowed, this function will - \e always return false when attempting to lock the file recursively. - - \sa lock(), unlock() -*/ - /*! \fn void QLockFile::unlock() Releases the lock, by deleting the lock file. diff --git a/src/corelib/io/qlockfile.h b/src/corelib/io/qlockfile.h index b63194dcd36..ccba93baa54 100644 --- a/src/corelib/io/qlockfile.h +++ b/src/corelib/io/qlockfile.h @@ -22,13 +22,20 @@ public: QString fileName() const; bool lock(); - bool tryLock(int timeout = 0); + bool tryLock(int timeout); void unlock(); void setStaleLockTime(int); int staleLockTime() const; - bool tryLock(std::chrono::milliseconds timeout) { return tryLock(int(timeout.count())); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + bool tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero()); +#else + bool tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero()) + { + return tryLock_impl(timeout); + } +#endif void setStaleLockTime(std::chrono::milliseconds value) { setStaleLockTime(int(value.count())); } @@ -55,6 +62,10 @@ protected: private: Q_DECLARE_PRIVATE(QLockFile) Q_DISABLE_COPY(QLockFile) + +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + bool tryLock_impl(std::chrono::milliseconds timeout); +#endif }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index aa40353c991..1f26dc785f6 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -26,6 +26,8 @@ #include // for getLockFileHandle() +using namespace std::chrono_literals; + class tst_QLockFile : public QObject { Q_OBJECT @@ -96,7 +98,7 @@ void tst_QLockFile::lockUnlock() QVERIFY(lockFile.getLockInfo(&pid, &hostname, &appname)); QCOMPARE(pid, QCoreApplication::applicationPid()); QCOMPARE(appname, qAppName()); - QVERIFY(!lockFile.tryLock(200)); + QVERIFY(!lockFile.tryLock(200ms)); QCOMPARE(int(lockFile.error()), int(QLockFile::LockFailedError)); // Unlock deletes the lock file @@ -341,8 +343,8 @@ void tst_QLockFile::staleLongLockFromBusyProcess() QTRY_VERIFY(QFile::exists(fileName)); QLockFile secondLock(fileName); - secondLock.setStaleLockTime(0); - QVERIFY(!secondLock.tryLock(100)); // never stale + secondLock.setStaleLockTime(0ms); + QVERIFY(!secondLock.tryLock(100ms)); // never stale QCOMPARE(int(secondLock.error()), int(QLockFile::LockFailedError)); qint64 pid; QTRY_VERIFY(secondLock.getLockInfo(&pid, NULL, NULL)); @@ -510,8 +512,8 @@ void tst_QLockFile::corruptedLockFile() } QLockFile secondLock(fileName); - secondLock.setStaleLockTime(100); - QVERIFY(secondLock.tryLock(10000)); + secondLock.setStaleLockTime(100ms); + QVERIFY(secondLock.tryLock(10s)); QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); } @@ -564,7 +566,7 @@ void tst_QLockFile::hostnameChange() { // we should fail to lock QLockFile lock2(lockFile); - QVERIFY(!lock2.tryLock(1000)); + QVERIFY(!lock2.tryLock(1s)); } } @@ -591,7 +593,7 @@ void tst_QLockFile::differentMachines() { // we should fail to lock QLockFile lock2(lockFile); - QVERIFY(!lock2.tryLock(1000)); + QVERIFY(!lock2.tryLock(1s)); } } @@ -620,7 +622,7 @@ void tst_QLockFile::reboot() f.close(); // we should succeed in locking - QVERIFY(lock1.tryLock(0)); + QVERIFY(lock1.tryLock(0ms)); } bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid)