diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2023-02-27 21:50:23 +0200 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2023-03-14 22:15:35 +0200 |
commit | 5cea5fc80b9e1b19d620ec6be1acd5cdbd220971 (patch) | |
tree | 23aa2bc463a9b384d982a24d1f5ce8be2ab9ad53 | |
parent | 425e635ecd8d588a87da66a1ef89fbf9ef469f1e (diff) |
QLockFile: tryLock(): use chrono first
I.e. tryLock(chrono::milliseconds) shouldn't call the int overload as
that truncates the timeout (milliseconds is typically int64_t).
Add a note to the tryLock(millisecons) docs that passing
milliseconds::max() will make it wait forever to obtain the lock.
Task-number: QTBUG-110059
Change-Id: Ib48d9b1b117ce816348625331543d6ba8a788973
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/io/qlockfile.cpp | 70 | ||||
-rw-r--r-- | src/corelib/io/qlockfile.h | 15 | ||||
-rw-r--r-- | tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 18 |
3 files changed, 65 insertions, 38 deletions
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 5a452226e0..1c061890a8 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<Msec>(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 b63194dcd3..ccba93baa5 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 aa40353c99..1f26dc785f 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -26,6 +26,8 @@ #include <private/qlockfile_p.h> // 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) |