QSemaphore: add <chrono> overload of tryAcquire()
... and C++20 std::counting_semaphore API compatibility. [ChangeLog][QtCore][QSemaphore] tryAcquire() now optionally takes a <chrono> duration as timeout, not just int milliseconds. [ChangeLog][QtCore][QSemaphore] Added try_acquire{,_for,_until}() for C++20 std::counting_semaphore compatibility. Change-Id: I34b6b4bf57a54745d4b97349903d090c4995338a Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
6f27255cd4
commit
38448b19a1
@ -485,6 +485,46 @@ bool QSemaphore::tryAcquire(int n, int timeout)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn template <typename Rep, typename Period> QSemaphore::tryAcquire(int n, std::chrono::duration<Rep, Period> timeout)
|
||||
\overload
|
||||
\since 6.3
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QSemaphore::try_acquire()
|
||||
\since 6.3
|
||||
|
||||
This function is provided for \c{std::counting_semaphore} compatibility.
|
||||
|
||||
It is equivalent to calling \c{tryAcquire(1)}.
|
||||
|
||||
\sa tryAcquire(), try_acquire_for(), try_acquire_until()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Rep, typename Period> QSemaphore::try_acquire_for(std::chrono::duration<Rep, Period> timeout)
|
||||
\since 6.3
|
||||
|
||||
This function is provided for \c{std::counting_semaphore} compatibility.
|
||||
|
||||
It is equivalent to calling \c{tryAcquire(1, timeout)}.
|
||||
|
||||
\sa tryAcquire(), try_acquire(), try_acquire_until()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Clock, typename Duration> QSemaphore::try_acquire_until(std::chrono::time_point<Clock, Duration> timeout)
|
||||
\since 6.3
|
||||
|
||||
This function is provided for \c{std::counting_semaphore} compatibility.
|
||||
|
||||
It is equivalent to calling \c{tryAcquire(1, timeout - Clock::now())},
|
||||
which means that adjustments to \c{Clock} are ignored while waiting.
|
||||
|
||||
\sa tryAcquire(), try_acquire(), try_acquire_for()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QSemaphoreReleaser
|
||||
\brief The QSemaphoreReleaser class provides exception-safe deferral of a QSemaphore::release() call.
|
||||
|
@ -41,6 +41,9 @@
|
||||
#define QSEMAPHORE_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qmutex.h> // for convertToMilliseconds()
|
||||
|
||||
#include <chrono>
|
||||
|
||||
QT_REQUIRE_CONFIG(thread);
|
||||
|
||||
@ -57,11 +60,24 @@ public:
|
||||
void acquire(int n = 1);
|
||||
bool tryAcquire(int n = 1);
|
||||
bool tryAcquire(int n, int timeout);
|
||||
template <typename Rep, typename Period>
|
||||
bool tryAcquire(int n, std::chrono::duration<Rep, Period> timeout)
|
||||
{ return tryAcquire(n, QtPrivate::convertToMilliseconds(timeout)); }
|
||||
|
||||
void release(int n = 1);
|
||||
|
||||
int available() const;
|
||||
|
||||
// std::counting_semaphore compatibility:
|
||||
bool try_acquire() noexcept { return tryAcquire(); }
|
||||
template <typename Rep, typename Period>
|
||||
bool try_acquire_for(const std::chrono::duration<Rep, Period> &timeout)
|
||||
{ return tryAcquire(1, timeout); }
|
||||
template <typename Clock, typename Duration>
|
||||
bool try_acquire_until(const std::chrono::time_point<Clock, Duration> &tp)
|
||||
{
|
||||
return try_acquire_for(tp - Clock::now());
|
||||
}
|
||||
private:
|
||||
Q_DISABLE_COPY(QSemaphore)
|
||||
|
||||
|
@ -32,6 +32,10 @@
|
||||
#include <qthread.h>
|
||||
#include <qsemaphore.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
class tst_QSemaphore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -47,6 +51,7 @@ private slots:
|
||||
void tryAcquireWithTimeoutForever();
|
||||
void producerConsumer();
|
||||
void raii();
|
||||
void stdCompat();
|
||||
};
|
||||
|
||||
static QSemaphore *semaphore = nullptr;
|
||||
@ -500,7 +505,7 @@ public:
|
||||
void run() override;
|
||||
};
|
||||
|
||||
static const int Timeout = 60 * 1000; // 1min
|
||||
static const auto Timeout = 1min;
|
||||
|
||||
void Producer::run()
|
||||
{
|
||||
@ -599,5 +604,34 @@ void tst_QSemaphore::raii()
|
||||
QCOMPARE(sem.available(), 49);
|
||||
}
|
||||
|
||||
void tst_QSemaphore::stdCompat()
|
||||
{
|
||||
QSemaphore sem(1);
|
||||
|
||||
auto now = [] { return std::chrono::steady_clock::now(); };
|
||||
|
||||
QVERIFY(sem.try_acquire());
|
||||
QCOMPARE(sem.available(), 0);
|
||||
QVERIFY(!sem.try_acquire_for(10ms));
|
||||
QCOMPARE(sem.available(), 0);
|
||||
QVERIFY(!sem.try_acquire_until(now() + 10ms));
|
||||
QCOMPARE(sem.available(), 0);
|
||||
|
||||
sem.release(2);
|
||||
|
||||
QVERIFY(sem.try_acquire());
|
||||
QVERIFY(sem.try_acquire_for(5ms));
|
||||
QCOMPARE(sem.available(), 0);
|
||||
QVERIFY(!sem.try_acquire_until(now() + 5ms));
|
||||
QCOMPARE(sem.available(), 0);
|
||||
|
||||
sem.release(3);
|
||||
|
||||
QVERIFY(sem.try_acquire());
|
||||
QVERIFY(sem.try_acquire_for(5s));
|
||||
QVERIFY(sem.try_acquire_until(now() + 5s));
|
||||
QCOMPARE(sem.available(), 0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSemaphore)
|
||||
#include "tst_qsemaphore.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user