summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2023-02-27 21:50:23 +0200
committerAhmad Samir <a.samirh78@gmail.com>2023-03-14 22:15:35 +0200
commit5cea5fc80b9e1b19d620ec6be1acd5cdbd220971 (patch)
tree23aa2bc463a9b384d982a24d1f5ce8be2ab9ad53
parent425e635ecd8d588a87da66a1ef89fbf9ef469f1e (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.cpp70
-rw-r--r--src/corelib/io/qlockfile.h15
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp18
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)