Long live QDeadlineTimer
It's like QElapsedTimer, but marks a time in the future instead. [ChangeLog][QtCore] Added QDeadlineTimer, a counterpart to QElapsedTimer, used to mark a time point in the future (a deadline) and determine whether such a deadline has passed. Change-Id: Ifea6e497f11a461db432ffff144921f7fbc1d1d3 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
906fc0f5e3
commit
12eacc3bab
@ -4,6 +4,8 @@ HEADERS += \
|
||||
kernel/qabstracteventdispatcher.h \
|
||||
kernel/qabstractnativeeventfilter.h \
|
||||
kernel/qbasictimer.h \
|
||||
kernel/qdeadlinetimer.h \
|
||||
kernel/qdeadlinetimer_p.h \
|
||||
kernel/qelapsedtimer.h \
|
||||
kernel/qeventloop.h\
|
||||
kernel/qpointer.h \
|
||||
@ -46,6 +48,7 @@ SOURCES += \
|
||||
kernel/qabstracteventdispatcher.cpp \
|
||||
kernel/qabstractnativeeventfilter.cpp \
|
||||
kernel/qbasictimer.cpp \
|
||||
kernel/qdeadlinetimer.cpp \
|
||||
kernel/qelapsedtimer.cpp \
|
||||
kernel/qeventloop.cpp \
|
||||
kernel/qcoreapplication.cpp \
|
||||
|
827
src/corelib/kernel/qdeadlinetimer.cpp
Normal file
827
src/corelib/kernel/qdeadlinetimer.cpp
Normal file
@ -0,0 +1,827 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdeadlinetimer.h"
|
||||
#include "qdeadlinetimer_p.h"
|
||||
#include <qpair.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64 nsecs)
|
||||
{
|
||||
qint64 secs = nsecs / (1000*1000*1000);
|
||||
if (nsecs < 0)
|
||||
--secs;
|
||||
nsecs -= secs * 1000*1000*1000;
|
||||
return qMakePair(secs, nsecs);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QDeadlineTimer
|
||||
\inmodule QtCore
|
||||
\brief The QDeadlineTimer class marks a deadline in the future.
|
||||
\since 5.8
|
||||
|
||||
\reentrant
|
||||
\ingroup tools
|
||||
|
||||
The QDeadlineTimer class is usually used to calculate future deadlines and
|
||||
verify whether the deadline has expired. QDeadlineTimer can also be used
|
||||
for deadlines without expiration ("forever"). It forms a counterpart to
|
||||
QElapsedTimer, which calculates how much time has elapsed since
|
||||
QElapsedTimer::start() was called.
|
||||
|
||||
QDeadlineTimer provides a more convenient API compared to
|
||||
QElapsedTimer::hasExpired().
|
||||
|
||||
The typical use-case for the class is to create a QDeadlineTimer before the
|
||||
operation in question is started, and then use remainingTime() or
|
||||
hasExpired() to determine whether to continue trying the operation.
|
||||
QDeadlineTimer objects can be passed to functions being called to execute
|
||||
this operation so they know how long to still operate.
|
||||
|
||||
\code
|
||||
void executeOperation(int msecs)
|
||||
{
|
||||
QDeadlineTimer deadline(msecs);
|
||||
do {
|
||||
if (readFromDevice(deadline.remainingTime())
|
||||
break;
|
||||
waitForReadyRead(deadline);
|
||||
} while (!deadline.hasExpired());
|
||||
}
|
||||
\endcode
|
||||
|
||||
Many QDeadlineTimer functions deal with time out values, which all are
|
||||
measured in milliseconds. There are two special values, the same as many
|
||||
other Qt functions named \c{waitFor} or similar:
|
||||
|
||||
\list
|
||||
\o 0: no time left, expired
|
||||
\o -1: infinite time left, timer never expires
|
||||
\endlist
|
||||
|
||||
\section1 Reference Clocks
|
||||
|
||||
QDeadlineTimer will use the same clock as QElapsedTimer (see
|
||||
QElapsedTimer::clockType() and QElapsedTimer::isMonotonic()).
|
||||
|
||||
\section1 Timer types
|
||||
|
||||
Like QTimer, QDeadlineTimer can select among different levels of coarseness
|
||||
on the timers. You can select precise timing by passing Qt::PreciseTimer to
|
||||
the functions that set of change the timer, or you can select coarse timing
|
||||
by passing Qt::CoarseTimer. Qt::VeryCoarseTimer is currently interpreted
|
||||
the same way as Qt::CoarseTimer.
|
||||
|
||||
This feature is dependent on support from the operating system: if the OS
|
||||
does not support a coarse timer functionality, then QDeadlineTimer will
|
||||
behave like Qt::PreciseTimer was passed.
|
||||
|
||||
QDeadlineTimer defaults to Qt::CoarseTimer because on operating systems
|
||||
that do support coarse timing, making timing calls to that clock source is
|
||||
often much more efficient. The level of coarseness depends on the
|
||||
operating system, but should be in the order of a couple of milliseconds.
|
||||
|
||||
\section1 \c{std::chrono} Compatibility
|
||||
|
||||
QDeadlineTimer is compatible with the \c{std::chrono} API from C++11 and
|
||||
can be constructed from or compared to both \c{std::chrono::duration} and
|
||||
\c{std::chrono::time_point} objects. In addition, it is fully compatible
|
||||
with the time literals from C++14, which allow one to write code as:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
|
||||
QDeadlineTimer deadline(30s);
|
||||
device->waitForReadyRead(deadline);
|
||||
if (deadline.remainingTime<nanoseconds>() > 300ms)
|
||||
cleanup();
|
||||
\endcode
|
||||
|
||||
As can be seen in the example above, QDeadlineTimer offers a templated
|
||||
version of remainingTime() and deadline() that can be used to return
|
||||
\c{std::chrono} objects.
|
||||
|
||||
Note that comparing to \c{time_point} is not as efficient as comparing to
|
||||
\c{duration}, since QDeadlineTimer may need to convert from its own
|
||||
internal clock source to the clock source used by the \c{time_point} object.
|
||||
Also note that, due to this conversion, the deadlines will not be precise,
|
||||
so the following code is not expected to compare equally:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
auto now = steady_clock::now();
|
||||
QDeadlineTimer deadline(now + 1s);
|
||||
Q_ASSERT(deadline == now + 1s);
|
||||
\endcode
|
||||
|
||||
\sa QTime, QTimer, QDeadlineTimer, Qt::TimerType
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QDeadlineTimer::ForeverConstant
|
||||
|
||||
\value Forever Used when creating a QDeadlineTimer to indicate the
|
||||
deadline should not expire
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer::QDeadlineTimer(Qt::TimerType timerType)
|
||||
|
||||
Constructs an expired QDeadlineTimer object. For this object,
|
||||
remainingTime() will return 0.
|
||||
|
||||
The timer type \a timerType may be ignored, since the timer is already
|
||||
expired. Similarly, for optimization purposes, this function will not
|
||||
attempt to obtain the current time and will use a value known to be in the
|
||||
past. Therefore, deadline() may return an unexpected value and this object
|
||||
cannot be used in calculation of how long it is overdue. If that
|
||||
functionality is required, use QDeadlineTimer::current().
|
||||
|
||||
\sa hasExpired(), remainingTime(), timerType(), current()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer::QDeadlineTimer(ForeverConstant, Qt::TimerType timerType)
|
||||
|
||||
Constructs a QDeadlineTimer object that never expires. For this object,
|
||||
remainingTime() will return -1, deadline() will return the maximum value,
|
||||
and isForever() will return true.
|
||||
|
||||
The timer type \a timerType may be ignored, since the timer is already
|
||||
expired.
|
||||
|
||||
\sa hasExpired(), isForever(), remainingTime(), timerType()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a QDeadlineTimer object with an expiry time of \a msecs msecs
|
||||
from the moment of the creation of this object, if msecs is positive. If \a
|
||||
msecs is zero, this QDeadlineTimer will be marked as expired, causing
|
||||
remainingTime() to return zero and deadline() to return an indeterminate
|
||||
time point in the past. If \a msecs is -1, the timer will be set it to
|
||||
never expire, causing remainingTime() to return -1 and deadline() to return
|
||||
the maximum value.
|
||||
|
||||
The QDeadlineTimer object will be constructed with a timer type of \a
|
||||
timerType.
|
||||
|
||||
For optimization purposes, if \a msecs is zero, this function may skip
|
||||
obtaining the current time and may instead use a value known to be in the
|
||||
past. If that happens, deadline() may return an unexpected value and this
|
||||
object cannot be used in calculation of how long it is overdue. If that
|
||||
functionality is required, use QDeadlineTimer::current() and add time to
|
||||
it.
|
||||
|
||||
\sa hasExpired(), isForever(), remainingTime(), setRemainingTime()
|
||||
*/
|
||||
QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
|
||||
: t2(0)
|
||||
{
|
||||
setRemainingTime(msecs, type);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer::QDeadlineTimer(std::chrono::time_point<Clock, Duration> deadline, Qt::TimerType type)
|
||||
|
||||
Constructs a QDeadlineTimer object with a deadline at \a deadline time
|
||||
point, converting from the clock source \c{Clock} to Qt's internal clock
|
||||
source (see QElapsedTimer::clcokType()).
|
||||
|
||||
If \a deadline is in the past, this QDeadlineTimer object is set to
|
||||
expired, whereas if \a deadline is equal to \c{Duration::max()}, then this
|
||||
object is set to never expire.
|
||||
|
||||
The QDeadlineTimer object will be constructed with a timer type of \a
|
||||
timerType.
|
||||
|
||||
\sa hasExpired(), isForever(), remainingTime<Duration>(), setDeadline()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer::QDeadlineTimer(std::chrono::duration<Rep, Period> remaining, Qt::TimerType type)
|
||||
|
||||
Constructs a QDeadlineTimer object with a remaining time of \a remaining.
|
||||
If \a remaining is zero or negative, this QDeadlineTimer object will be
|
||||
mark as expired, whereas if \a remaining is equal to \c{duration::max()},
|
||||
the object will be set to never expire.
|
||||
|
||||
The QDeadlineTimer object will be constructed with a timer type of \a
|
||||
timerType.
|
||||
|
||||
This constructor can be used with C++14's user-defined literals for time, such as in:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
QDeadlineTimer deadline(250ms);
|
||||
\endcode
|
||||
|
||||
For optimization purposes, if \a remaining is zero or negative, this
|
||||
function may skip obtaining the current time and may instead use a value
|
||||
known to be in the past. If that happens, deadline() may return an
|
||||
unexpected value and this object cannot be used in calculation of how long
|
||||
it is overdue. If that functionality is required, use
|
||||
QDeadlineTimer::current() and add time to it.
|
||||
|
||||
\sa hasExpired(), isForever(), remainingTime<Duration>(), setRemainingTime()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QDeadlineTimer::setDeadline(std::chrono::time_point<Clock, Duration> deadline, Qt::TimerType type)
|
||||
|
||||
Sets this QDeadlineTimer to the deadline marked by \a deadline time
|
||||
point, converting from the clock source \c{Clock} to Qt's internal clock
|
||||
source (see QElapsedTimer::clcokType()).
|
||||
|
||||
If \a deadline is in the past, this QDeadlineTimer object is set to
|
||||
expired, whereas if \a deadline is equal to \c{Duration::max()}, then this
|
||||
object is set to never expire.
|
||||
|
||||
The timer type for this QDeadlineTimer object will be set to \a timerType type.
|
||||
|
||||
\sa hasExpired(), isForever(), remainingTime<Duration>(),
|
||||
*/
|
||||
|
||||
/*!
|
||||
Sets the remaining time for this QDeadlineTimer object to \a msecs
|
||||
milliseconds from now, if \a msecs has a positive value. If \a msecs is
|
||||
zero, this QDeadlineTimer object will be marked as expired, whereas a value
|
||||
of -1 will set it to never expire.
|
||||
|
||||
The timer type for this QDeadlineTimer object will be set to \a timerType type.
|
||||
|
||||
\sa setPreciseRemainingTime(), hasExpired(), isForever(), remainingTime()
|
||||
*/
|
||||
void QDeadlineTimer::setRemainingTime(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
if (msecs == -1)
|
||||
*this = QDeadlineTimer(Forever, timerType);
|
||||
else
|
||||
setPreciseRemainingTime(0, msecs * 1000 * 1000, timerType);
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the remaining time for this QDeadlineTimer object to \a secs seconds
|
||||
plus \a nsecs nanoseconds from now, if \a secs has a positive value. If \a
|
||||
secs is -1, this QDeadlineTimer will be set it to never expire. If both
|
||||
parameters are zero, this QDeadlineTimer will be marked as expired.
|
||||
|
||||
The timer type for this QDeadlineTimer object will be set to \a timerType type.
|
||||
|
||||
\sa setRemainingTime(), hasExpired(), isForever(), remainingTime()
|
||||
*/
|
||||
void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
if (secs == -1) {
|
||||
*this = QDeadlineTimer(Forever, timerType);
|
||||
return;
|
||||
}
|
||||
|
||||
*this = current(timerType);
|
||||
if (QDeadlineTimerNanosecondsInT2) {
|
||||
t1 += secs + toSecsAndNSecs(nsecs).first;
|
||||
t2 += toSecsAndNSecs(nsecs).second;
|
||||
if (t2 > 1000*1000*1000) {
|
||||
t2 -= 1000*1000*1000;
|
||||
++t1;
|
||||
}
|
||||
} else {
|
||||
t1 += secs * 1000 * 1000 * 1000 + nsecs;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\fn void QDeadlineTimer::setRemainingTime(std::chrono::duration<Rep, Period> remaining, Qt::TimerType type)
|
||||
|
||||
Sets the remaining time for this QDeadlineTimer object to \a remaining. If
|
||||
\a remaining is zero or negative, this QDeadlineTimer object will be mark
|
||||
as expired, whereas if \a remaining is equal to \c{duration::max()}, the
|
||||
object will be set to never expire.
|
||||
|
||||
The timer type for this QDeadlineTimer object will be set to \a timerType type.
|
||||
|
||||
This function can be used with C++14's user-defined literals for time, such as in:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
deadline.setRemainingTime(250ms);
|
||||
\endcode
|
||||
|
||||
\sa setDeadline(), remainingTime<Duration>(), hasExpired(), isForever()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, unsigned nsecs, Qt::TimerType type)
|
||||
|
||||
Sets the remaining time for this QDeadlineTimer object to \a secs seconds
|
||||
and \a nsecs nanoseconds from now, if \a secs is a positive value. If both
|
||||
values are zero, this QDeadlineTimer object will be marked as expired,
|
||||
whereas if \a secs is -1, it will set it to never expire.
|
||||
|
||||
If value of \a nsecs is more than 1 billion nanoseconds (1 second), this
|
||||
function will adjust \a secs accordingly.
|
||||
|
||||
The timer type for this QDeadlineTimer object will be set to \a timerType type.
|
||||
|
||||
\sa setRemainingTime(), hasExpired(), isForever(), remainingTime()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\fn Duration QDeadlineTimer::remainingTime() const
|
||||
|
||||
Returns a \c{std::chrono::duration} object of type \c{Duration} containing
|
||||
the remaining time in this QDeadlineTimer, if it still has time left. If
|
||||
the deadline has passed, this returns \c{Duration::zero()}, whereas if the
|
||||
object is set to never expire, it returns \c{Duration::max()} (instead of
|
||||
-1).
|
||||
|
||||
It is not possible to obtain the overdue time for expired timers with this
|
||||
function. To do that, see deadline().
|
||||
|
||||
\note The overload of this function without template parameter always
|
||||
returns milliseconds.
|
||||
|
||||
\sa setRemainingTime(), deadline<Clock, Duration>()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\fn std::chrono::time_point<Clock, Duration> QDeadlineTimer::deadline() const
|
||||
|
||||
Returns the absolute time point for the deadline stored in QDeadlineTimer
|
||||
object as a \c{std::chrono::time_point} object. The template parameter
|
||||
\c{Clock} is mandatory and indicates which of the C++ timekeeping clocks to
|
||||
use as a reference. The value will be in the past if this QDeadlineTimer
|
||||
has expired.
|
||||
|
||||
If this QDeadlineTimer never expires, this function returns
|
||||
\c{std::chrono::time_point<Clock, Duration>::max()}.
|
||||
|
||||
This function can be used to calculate the amount of time a timer is
|
||||
overdue, by subtracting the current time point of the reference clock, as
|
||||
in the following example:
|
||||
|
||||
\code
|
||||
auto realTimeLeft = std::chrono::nanoseconds::max();
|
||||
auto tp = deadline.deadline<std::chrono::steady_clock>();
|
||||
if (tp != std::chrono::steady_clock::max())
|
||||
realTimeLeft = tp - std::chrono::steady_clock::now();
|
||||
\endcode
|
||||
|
||||
\note Timers that were created as expired have an indetermine time point in
|
||||
the past as their deadline, so the above calculation may not work.
|
||||
|
||||
\sa remainingTime(), deadlineNSecs(), setDeadline()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns true if this QDeadlineTimer object never expires, false otherwise.
|
||||
For timers that never expire, remainingTime() always returns -1 and
|
||||
deadline() returns the maximum value.
|
||||
|
||||
\sa ForeverConstant, hasExpired(), remainingTime()
|
||||
*/
|
||||
bool QDeadlineTimer::isForever() const Q_DECL_NOTHROW
|
||||
{
|
||||
return t1 == (std::numeric_limits<qint64>::max)();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this QDeadlineTimer object has expired, false if there
|
||||
remains time left. For objects that have expired, remainingTime() will
|
||||
return zero and deadline() will return a time point in the past.
|
||||
|
||||
QDeadlineTimer objects created with the \ref{ForeverConstant} never expire
|
||||
and this function always returns false for them.
|
||||
|
||||
\sa isForever(), remainingTime()
|
||||
*/
|
||||
bool QDeadlineTimer::hasExpired() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isForever())
|
||||
return false;
|
||||
return *this <= current(timerType());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn Qt::TimerType QDeadlineTimer::timerType() const Q_DECL_NOTHROW
|
||||
|
||||
Returns the timer type is active for this object.
|
||||
|
||||
\sa setTimerType()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Changes the timer type for this object to \a timerType.
|
||||
|
||||
The behavior for each possible value of \a timerType is operating-system
|
||||
dependent. Qt::PreciseTimer will use the most precise timer that Qt can
|
||||
find, with resolution of 1 millisecond or better, whereas QDeadlineTimer
|
||||
will try to use a more coarse timer for Qt::CoarseTimer and
|
||||
Qt::VeryCoarseTimer.
|
||||
|
||||
\sa timerType()
|
||||
*/
|
||||
void QDeadlineTimer::setTimerType(Qt::TimerType timerType)
|
||||
{
|
||||
type = timerType;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the remaining time in this QDeadlineTimer object in milliseconds.
|
||||
If the timer has already expired, this function will return zero and it is
|
||||
not possible to obtain the amount of time overdue with this function (to do
|
||||
that, see deadline()). If the timer was set to never expire, this function
|
||||
returns -1.
|
||||
|
||||
This function is suitable for use in Qt APIs that take a millisecond
|
||||
timeout, such as the many \ref QIODevice \c waitFor functions or the timed
|
||||
lock functions in \ref QMutex, \ref QWaitCondition, \ref QSemaphore, or
|
||||
\ref QReadWriteLock. For example:
|
||||
|
||||
\code
|
||||
mutex.tryLock(deadline.remainingTime());
|
||||
\code
|
||||
|
||||
\sa remainingTimeNSecs(), isForever(), hasExpired()
|
||||
*/
|
||||
qint64 QDeadlineTimer::remainingTime() const Q_DECL_NOTHROW
|
||||
{
|
||||
qint64 ns = remainingTimeNSecs();
|
||||
return ns <= 0 ? ns : ns / (1000 * 1000);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the remaining time in this QDeadlineTimer object in nanoseconds. If
|
||||
the timer has already expired, this function will return zero and it is not
|
||||
possible to obtain the amount of time overdue with this function. If the
|
||||
timer was set to never expire, this function returns -1.
|
||||
|
||||
\sa remainingTime(), isForever(), hasExpired()
|
||||
*/
|
||||
qint64 QDeadlineTimer::remainingTimeNSecs() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isForever())
|
||||
return -1;
|
||||
qint64 raw = rawRemainingTimeNSecs();
|
||||
return raw < 0 ? 0 : raw;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Same as remainingTimeNSecs, but may return negative remaining times. Does
|
||||
not deal with Forever.
|
||||
*/
|
||||
qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW
|
||||
{
|
||||
QDeadlineTimer now = current(timerType());
|
||||
if (QDeadlineTimerNanosecondsInT2)
|
||||
return (t1 - now.t1) * (1000*1000*1000) + t2 - now.t2;
|
||||
return t1 - now.t1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the absolute time point for the deadline stored in QDeadlineTimer
|
||||
object, calculated in milliseconds relative to the reference clock, the
|
||||
same as QElapsedTimer::msecsSinceReference(). The value will be in the past
|
||||
if this QDeadlineTimer has expired.
|
||||
|
||||
If this QDeadlineTimer never expires, this function returns
|
||||
\c{std::numeric_limits<qint64>::max()}.
|
||||
|
||||
This function can be used to calculate the amount of time a timer is
|
||||
overdue, by subtracting QDeadlineTimer::current() or
|
||||
QElapsedTimer::msecsSinceReference(), as in the following example:
|
||||
|
||||
\code
|
||||
qint64 realTimeLeft = deadline.deadline();
|
||||
if (realTimeLeft != (std::numeric_limits<qint64>::max)()) {
|
||||
realTimeLeft -= QDeadlineTimer::current().deadline();
|
||||
// or:
|
||||
//QElapsedTimer timer;
|
||||
//timer.start();
|
||||
//realTimeLeft -= timer.msecsSinceReference();
|
||||
}
|
||||
\endcode
|
||||
|
||||
\note Timers that were created as expired have an indetermine time point in
|
||||
the past as their deadline, so the above calculation may not work.
|
||||
|
||||
\sa remainingTime(), deadlineNSecs(), setDeadline()
|
||||
*/
|
||||
qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isForever())
|
||||
return t1;
|
||||
return deadlineNSecs() / (1000 * 1000);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the absolute time point for the deadline stored in QDeadlineTimer
|
||||
object, calculated in nanoseconds relative to the reference clock, the
|
||||
same as QElapsedTimer::msecsSinceReference(). The value will be in the past
|
||||
if this QDeadlineTimer has expired.
|
||||
|
||||
If this QDeadlineTimer never expires, this function returns
|
||||
\c{std::numeric_limits<qint64>::max()}.
|
||||
|
||||
This function can be used to calculate the amount of time a timer is
|
||||
overdue, by subtracting QDeadlineTimer::current(), as in the following
|
||||
example:
|
||||
|
||||
\code
|
||||
qint64 realTimeLeft = deadline.deadlineNSecs();
|
||||
if (realTimeLeft != std::numeric_limits<qint64>::max())
|
||||
realTimeLeft -= QDeadlineTimer::current().deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note Timers that were created as expired have an indetermine time point in
|
||||
the past as their deadline, so the above calculation may not work.
|
||||
|
||||
\sa remainingTime(), deadlineNSecs()
|
||||
*/
|
||||
qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isForever())
|
||||
return t1;
|
||||
if (QDeadlineTimerNanosecondsInT2)
|
||||
return t1 * 1000 * 1000 * 1000 + t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the deadline for this QDeadlineTimer object to be the \a msecs
|
||||
absolute time point, counted in milliseconds since the reference clock (the
|
||||
same as QElapsedTimer::msecsSinceReference()), and the timer type to \a
|
||||
timerType. If the value is in the past, this QDeadlineTimer will be marked
|
||||
as expired.
|
||||
|
||||
If \a msecs is \c{std::numeric_limits<qint64>::max()}, this QDeadlineTimer
|
||||
will be set to never expire.
|
||||
|
||||
\sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime()
|
||||
*/
|
||||
void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
if (msecs == (std::numeric_limits<qint64>::max)()) {
|
||||
setPreciseDeadline(msecs, 0, timerType); // msecs == MAX implies Forever
|
||||
} else {
|
||||
setPreciseDeadline(msecs / 1000, msecs % 1000 * 1000 * 1000, timerType);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the deadline for this QDeadlineTimer object to be \a secs seconds and
|
||||
\a nsecs nanoseconds since the reference clock epoch (the same as
|
||||
QElapsedTimer::msecsSinceReference()), and the timer type to \a timerType.
|
||||
If the value is in the past, this QDeadlineTimer will be marked as expired.
|
||||
|
||||
If \a secs or \a nsecs is \c{std::numeric_limits<qint64>::max()}, this
|
||||
QDeadlineTimer will be set to never expire. If \a nsecs is more than 1
|
||||
billion nanoseconds (1 second), then \a secs will be adjusted accordingly.
|
||||
|
||||
\sa setDeadline(), deadline(), deadlineNSecs(), setRemainingTime()
|
||||
*/
|
||||
void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
type = timerType;
|
||||
if (secs == (std::numeric_limits<qint64>::max)() || nsecs == (std::numeric_limits<qint64>::max)()) {
|
||||
*this = QDeadlineTimer(Forever, timerType);
|
||||
} else if (QDeadlineTimerNanosecondsInT2) {
|
||||
t1 = secs + toSecsAndNSecs(nsecs).first;
|
||||
t2 = toSecsAndNSecs(nsecs).second;
|
||||
} else {
|
||||
t1 = secs * (1000*1000*1000) + nsecs;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a QDeadlineTimer object whose deadline is extended from \a dt's
|
||||
deadline by \a nsecs nanoseconds. If \a dt was set to never expire, this
|
||||
function returns a QDeadlineTimer that will not expire either.
|
||||
|
||||
\note if \a dt was created as expired, its deadline is indeterminate and
|
||||
adding an amount of time may or may not cause it to become unexpired.
|
||||
*/
|
||||
QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_NOTHROW
|
||||
{
|
||||
if (dt.isForever() || nsecs == (std::numeric_limits<qint64>::max)()) {
|
||||
dt = QDeadlineTimer(Forever, dt.timerType());
|
||||
} else if (QDeadlineTimerNanosecondsInT2) {
|
||||
dt.t1 += toSecsAndNSecs(nsecs).first;
|
||||
dt.t2 += toSecsAndNSecs(nsecs).second;
|
||||
if (dt.t2 > 1000*1000*1000) {
|
||||
dt.t2 -= 1000*1000*1000;
|
||||
++dt.t1;
|
||||
}
|
||||
} else {
|
||||
dt.t1 += nsecs;
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer QDeadlineTimer::current(Qt::TimerType timerType)
|
||||
|
||||
Returns a QDeadlineTimer that is expired but is guaranteed to contain the
|
||||
current time. Objects created by this function can participate in the
|
||||
calculation of how long a timer is overdue, using the deadline() function.
|
||||
|
||||
The QDeadlineTimer object will be constructed with a timer type of \a
|
||||
timerType.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn qint64 QDeadlineTimer::resolution(Qt::TimerType timerType)
|
||||
|
||||
Returns the resolution in nanoseconds of the system clock that backs timers
|
||||
of type \a timerType, or 0 if the resolution could not be determined.
|
||||
|
||||
The resolution is not a guarantee that applications will get time values
|
||||
with an accuracy down to that level. It is only the minimum change value
|
||||
that can be expected.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator==(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 and the deadline in \a d2 are the
|
||||
same, false otherwise. The timer type used to create the two deadlines is
|
||||
ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() == d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator!=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 and the deadline in \a d2 are
|
||||
diferent, false otherwise. The timer type used to create the two deadlines
|
||||
is ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() != d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator<(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 is earlier than the deadline in \a
|
||||
d2, false otherwise. The timer type used to create the two deadlines is
|
||||
ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() < d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator<=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 is earlier than or the same as the
|
||||
deadline in \a d2, false otherwise. The timer type used to create the two
|
||||
deadlines is ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() <= d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator>(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 is later than the deadline in \a
|
||||
d2, false otherwise. The timer type used to create the two deadlines is
|
||||
ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() > d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns true if the deadline on \a d1 is later than or the same as the
|
||||
deadline in \a d2, false otherwise. The timer type used to create the two
|
||||
deadlines is ignored. This function is equivalent to:
|
||||
|
||||
\code
|
||||
return d1.deadlineNSecs() >= d2.deadlineNSecs();
|
||||
\endcode
|
||||
|
||||
\note comparing QDeadlineTimer objects with different timer types is
|
||||
not supported and may result in unpredictable behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns a QDeadlineTimer object whose deadline is \a msecs later than the
|
||||
deadline stored in \a dt. If \a dt is set to never expire, this function
|
||||
returns a QDeadlineTimer that does not expire either.
|
||||
|
||||
To add times of precision greater than 1 millisecond, use addNSecs().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns a QDeadlineTimer object whose deadline is \a msecs later than the
|
||||
deadline stored in \a dt. If \a dt is set to never expire, this function
|
||||
returns a QDeadlineTimer that does not expire either.
|
||||
|
||||
To add times of precision greater than 1 millisecond, use addNSecs().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)
|
||||
\related QDeadlineTimer
|
||||
|
||||
Returns a QDeadlineTimer object whose deadline is \a msecs before the
|
||||
deadline stored in \a dt. If \a dt is set to never expire, this function
|
||||
returns a QDeadlineTimer that does not expire either.
|
||||
|
||||
To subtract times of precision greater than 1 millisecond, use addNSecs().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer &QDeadlineTimer::operator+=(qint64 msecs)
|
||||
|
||||
Extends this QDeadlineTimer object by \a msecs milliseconds and returns
|
||||
itself. If this object is set to never expire, this function does nothing.
|
||||
|
||||
To add times of precision greater than 1 millisecond, use addNSecs().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDeadlineTimer &QDeadlineTimer::operator-=(qint64 msecs)
|
||||
|
||||
Shortens this QDeadlineTimer object by \a msecs milliseconds and returns
|
||||
itself. If this object is set to never expire, this function does nothing.
|
||||
|
||||
To subtract times of precision greater than 1 millisecond, use addNSecs().
|
||||
*/
|
||||
|
||||
// the rest of the functions are in qelapsedtimer_xxx.cpp
|
||||
|
||||
QT_END_NAMESPACE
|
190
src/corelib/kernel/qdeadlinetimer.h
Normal file
190
src/corelib/kernel/qdeadlinetimer.h
Normal file
@ -0,0 +1,190 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDEADLINETIMER_H
|
||||
#define QDEADLINETIMER_H
|
||||
|
||||
#include <QtCore/qelapsedtimer.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#ifdef max
|
||||
// un-pollute the namespace. We need std::numeric_limits::max() and std::chrono::duration::max()
|
||||
# undef max
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_CORE_EXPORT QDeadlineTimer
|
||||
{
|
||||
public:
|
||||
enum ForeverConstant { Forever };
|
||||
|
||||
Q_DECL_CONSTEXPR QDeadlineTimer(Qt::TimerType type_ = Qt::CoarseTimer) Q_DECL_NOTHROW
|
||||
: t1(0), t2(0), type(type_) {}
|
||||
Q_DECL_CONSTEXPR QDeadlineTimer(ForeverConstant, Qt::TimerType type_ = Qt::CoarseTimer) Q_DECL_NOTHROW
|
||||
: t1(std::numeric_limits<qint64>::max()), t2(0), type(type_) {}
|
||||
explicit QDeadlineTimer(qint64 msecs, Qt::TimerType type = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
|
||||
void swap(QDeadlineTimer &other)
|
||||
{ qSwap(t1, other.t1); qSwap(t2, other.t2); qSwap(type, other.type); }
|
||||
|
||||
bool isForever() const Q_DECL_NOTHROW;
|
||||
bool hasExpired() const Q_DECL_NOTHROW;
|
||||
|
||||
Qt::TimerType timerType() const Q_DECL_NOTHROW
|
||||
{ return Qt::TimerType(type & 0xff); }
|
||||
void setTimerType(Qt::TimerType type);
|
||||
|
||||
qint64 remainingTime() const Q_DECL_NOTHROW;
|
||||
qint64 remainingTimeNSecs() const Q_DECL_NOTHROW;
|
||||
void setRemainingTime(qint64 msecs, Qt::TimerType type = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
void setPreciseRemainingTime(qint64 secs, qint64 nsecs = 0,
|
||||
Qt::TimerType type = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
|
||||
qint64 deadline() const Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION;
|
||||
qint64 deadlineNSecs() const Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION;
|
||||
void setDeadline(qint64 msecs, Qt::TimerType timerType = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
void setPreciseDeadline(qint64 secs, qint64 nsecs = 0,
|
||||
Qt::TimerType type = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
|
||||
static QDeadlineTimer addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION;
|
||||
static QDeadlineTimer current(Qt::TimerType timerType = Qt::CoarseTimer) Q_DECL_NOTHROW;
|
||||
|
||||
friend bool operator==(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return d1.t1 == d2.t1 && d1.t2 == d2.t2; }
|
||||
friend bool operator!=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return !(d1 == d2); }
|
||||
friend bool operator<(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return d1.t1 < d2.t1 || (d1.t1 == d2.t1 && d1.t2 < d2.t2); }
|
||||
friend bool operator<=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return d1 == d2 || d1 < d2; }
|
||||
friend bool operator>(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return d2 < d1; }
|
||||
friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2)
|
||||
{ return !(d1 < d2); }
|
||||
|
||||
friend QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
|
||||
{ return QDeadlineTimer::addNSecs(dt, msecs * 1000 * 1000); }
|
||||
friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
|
||||
{ return dt + msecs; }
|
||||
friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)
|
||||
{ return dt + (-msecs); }
|
||||
friend qint64 operator-(QDeadlineTimer dt1, QDeadlineTimer dt2)
|
||||
{ return (dt1.deadlineNSecs() - dt2.deadlineNSecs()) / (1000 * 1000); }
|
||||
QDeadlineTimer &operator+=(qint64 msecs)
|
||||
{ *this = *this + msecs; return *this; }
|
||||
QDeadlineTimer &operator-=(qint64 msecs)
|
||||
{ *this = *this + (-msecs); return *this; }
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC)
|
||||
template <class Clock, class Duration>
|
||||
QDeadlineTimer(std::chrono::time_point<Clock, Duration> deadline_,
|
||||
Qt::TimerType type_ = Qt::CoarseTimer) : t2(0)
|
||||
{ setDeadline(deadline_, type_); }
|
||||
template <class Clock, class Duration>
|
||||
QDeadlineTimer &operator=(std::chrono::time_point<Clock, Duration> deadline_)
|
||||
{ setDeadline(deadline_); return *this; }
|
||||
|
||||
template <class Clock, class Duration>
|
||||
void setDeadline(std::chrono::time_point<Clock, Duration> deadline_,
|
||||
Qt::TimerType type_ = Qt::CoarseTimer)
|
||||
{ setRemainingTime(deadline_ == deadline_.max() ? Duration::max() : deadline_ - Clock::now(), type_); }
|
||||
|
||||
template <class Clock, class Duration = typename Clock::duration>
|
||||
std::chrono::time_point<Clock, Duration> deadline() const
|
||||
{
|
||||
auto val = std::chrono::nanoseconds(rawRemainingTimeNSecs()) + Clock::now();
|
||||
return std::chrono::time_point_cast<Duration>(val);
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
QDeadlineTimer(std::chrono::duration<Rep, Period> remaining, Qt::TimerType type_ = Qt::CoarseTimer)
|
||||
: t2(0)
|
||||
{ setRemainingTime(remaining, type_); }
|
||||
|
||||
template <class Rep, class Period>
|
||||
QDeadlineTimer &operator=(std::chrono::duration<Rep, Period> remaining)
|
||||
{ setRemainingTime(remaining); return *this; }
|
||||
|
||||
template <class Rep, class Period>
|
||||
void setRemainingTime(std::chrono::duration<Rep, Period> remaining, Qt::TimerType type_ = Qt::CoarseTimer)
|
||||
{
|
||||
if (remaining == remaining.max())
|
||||
*this = QDeadlineTimer(Forever, type_);
|
||||
else
|
||||
setPreciseRemainingTime(0, std::chrono::nanoseconds(remaining).count(), type_);
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds remainingTimeAsDuration() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isForever())
|
||||
return std::chrono::nanoseconds::max();
|
||||
qint64 nsecs = rawRemainingTimeNSecs();
|
||||
if (nsecs <= 0)
|
||||
return std::chrono::nanoseconds::zero();
|
||||
return std::chrono::nanoseconds(nsecs);
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
friend QDeadlineTimer operator+(QDeadlineTimer dt, std::chrono::duration<Rep, Period> value)
|
||||
{ return QDeadlineTimer::addNSecs(dt, std::chrono::duration_cast<std::chrono::nanoseconds>(value).count()); }
|
||||
template <class Rep, class Period>
|
||||
friend QDeadlineTimer operator+(std::chrono::duration<Rep, Period> value, QDeadlineTimer dt)
|
||||
{ return dt + value; }
|
||||
template <class Rep, class Period>
|
||||
friend QDeadlineTimer operator+=(QDeadlineTimer &dt, std::chrono::duration<Rep, Period> value)
|
||||
{ return dt = dt + value; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
qint64 t1;
|
||||
unsigned t2;
|
||||
unsigned type;
|
||||
|
||||
qint64 rawRemainingTimeNSecs() const Q_DECL_NOTHROW;
|
||||
};
|
||||
|
||||
Q_DECLARE_SHARED(QDeadlineTimer)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QDeadlineTimer)
|
||||
|
||||
#endif // QDEADLINETIMER_H
|
59
src/corelib/kernel/qdeadlinetimer_p.h
Normal file
59
src/corelib/kernel/qdeadlinetimer_p.h
Normal file
@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDEADLINETIMER_P_H
|
||||
#define QDEADLINETIMER_P_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum {
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
||||
// t1 contains seconds and t2 contains nanoseconds
|
||||
QDeadlineTimerNanosecondsInT2 = 1
|
||||
#else
|
||||
// t1 contains nanoseconds, t2 is always zero
|
||||
QDeadlineTimerNanosecondsInT2 = 0
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -83,6 +83,9 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
\snippet qelapsedtimer/main.cpp 2
|
||||
|
||||
It is often more convenient to use \ref{QDeadlineTimer} in this case, which
|
||||
counts towards a timeout in the future instead of tracking elapsed time.
|
||||
|
||||
\section1 Reference Clocks
|
||||
|
||||
QElapsedTimer will use the platform's monotonic reference clock in all
|
||||
@ -120,7 +123,7 @@ QT_BEGIN_NAMESPACE
|
||||
The information on which clocks types may overflow and how to remedy that
|
||||
issue is documented along with the clock types.
|
||||
|
||||
\sa QTime, QTimer
|
||||
\sa QTime, QTimer, QDeadlineTimer
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -255,7 +258,7 @@ bool QElapsedTimer::isValid() const Q_DECL_NOTHROW
|
||||
The value of \a timeout can be -1 to indicate that this timer does not
|
||||
expire, in which case this function will always return false.
|
||||
|
||||
\sa elapsed()
|
||||
\sa elapsed(), QDeadlineTimer
|
||||
*/
|
||||
bool QElapsedTimer::hasExpired(qint64 timeout) const Q_DECL_NOTHROW
|
||||
{
|
||||
|
@ -38,6 +38,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qdeadlinetimer.h"
|
||||
#include "qdatetime.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -201,4 +202,12 @@ bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW
|
||||
return v1.t1 < v2.t1;
|
||||
}
|
||||
|
||||
QDeadlineTimer QDeadlineTimer::current(Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
QDeadlineTimer result;
|
||||
result.t1 = QDateTime::currentMSecsSinceEpoch() * 1000 * 1000;
|
||||
result.type = timerType;
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -41,6 +41,8 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qdeadlinetimer.h"
|
||||
#include "qdeadlinetimer_p.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
@ -50,6 +52,12 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef __LP64__
|
||||
typedef __int128_t LargeInt;
|
||||
#else
|
||||
typedef qint64 LargeInt;
|
||||
#endif
|
||||
|
||||
QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW
|
||||
{
|
||||
return MachAbsoluteTime;
|
||||
@ -65,13 +73,13 @@ static qint64 absoluteToNSecs(qint64 cpuTime)
|
||||
{
|
||||
if (info.denom == 0)
|
||||
mach_timebase_info(&info);
|
||||
#ifdef __LP64__
|
||||
__uint128_t nsecs = static_cast<__uint128_t>(cpuTime) * info.numer / info.denom;
|
||||
return static_cast<qint64>(nsecs);
|
||||
#else
|
||||
qint64 nsecs = cpuTime * info.numer / info.denom;
|
||||
|
||||
// don't do multiplication & division if those are equal
|
||||
// (mathematically it would be the same, but it's computationally expensive)
|
||||
if (info.numer == info.denom)
|
||||
return cpuTime;
|
||||
qint64 nsecs = LargeInt(cpuTime) * info.numer / info.denom;
|
||||
return nsecs;
|
||||
#endif
|
||||
}
|
||||
|
||||
static qint64 absoluteToMSecs(qint64 cpuTime)
|
||||
@ -146,4 +154,13 @@ bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW
|
||||
return v1.t1 < v2.t1;
|
||||
}
|
||||
|
||||
QDeadlineTimer QDeadlineTimer::current(Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
Q_STATIC_ASSERT(!QDeadlineTimerNanosecondsInT2);
|
||||
QDeadlineTimer result;
|
||||
result.type = timerType;
|
||||
result.t1 = absoluteToNSecs(mach_absolute_time());
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -39,6 +39,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qdeadlinetimer.h"
|
||||
#include "qdeadlinetimer_p.h"
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
#include "qfunctions_vxworks.h"
|
||||
#else
|
||||
@ -248,4 +250,16 @@ bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW
|
||||
return v1.t1 < v2.t1 || (v1.t1 == v2.t1 && v1.t2 < v2.t2);
|
||||
}
|
||||
|
||||
QDeadlineTimer QDeadlineTimer::current(Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2);
|
||||
QDeadlineTimer result;
|
||||
qint64 cursec, curnsec;
|
||||
do_gettime(&cursec, &curnsec);
|
||||
result.t1 = cursec;
|
||||
result.t2 = curnsec;
|
||||
result.type = timerType;
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -38,6 +38,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qdeadlinetimer.h"
|
||||
#include "qdeadlinetimer_p.h"
|
||||
#include <qt_windows.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -76,6 +78,17 @@ static inline qint64 ticksToNanoseconds(qint64 ticks)
|
||||
}
|
||||
}
|
||||
|
||||
static inline qint64 nanosecondsToTicks(qint64 nsec)
|
||||
{
|
||||
if (counterFrequency > 0) {
|
||||
// QueryPerformanceCounter uses an arbitrary frequency
|
||||
return double(nsec) * counterFrequency / 1000000000.;
|
||||
} else {
|
||||
// GetTickCount(64) uses milliseconds
|
||||
return nsec / 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
static quint64 getTickCount()
|
||||
{
|
||||
resolveCounterFrequency();
|
||||
@ -161,4 +174,13 @@ bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW
|
||||
return (v1.t1 - v2.t1) < 0;
|
||||
}
|
||||
|
||||
QDeadlineTimer QDeadlineTimer::current(Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||
{
|
||||
Q_STATIC_ASSERT(!QDeadlineTimerNanosecondsInT2);
|
||||
QDeadlineTimer result;
|
||||
result.t1 = ticksToNanoseconds(getTickCount());
|
||||
result.type = timerType;
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -1,6 +1,7 @@
|
||||
TEMPLATE=subdirs
|
||||
SUBDIRS=\
|
||||
qcoreapplication \
|
||||
qdeadlinetimer \
|
||||
qelapsedtimer \
|
||||
qeventdispatcher \
|
||||
qeventloop \
|
||||
|
@ -0,0 +1,5 @@
|
||||
CONFIG += testcase
|
||||
TARGET = tst_qdeadlinetimer
|
||||
QT = core testlib
|
||||
SOURCES = tst_qdeadlinetimer.cpp
|
||||
|
625
tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
Normal file
625
tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
Normal file
@ -0,0 +1,625 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QDeadlineTimer>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
static const int minResolution = 100; // the minimum resolution for the tests
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::TimerType)
|
||||
|
||||
class tst_QDeadlineTimer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase_data();
|
||||
void basics();
|
||||
void foreverness();
|
||||
void current();
|
||||
void deadlines();
|
||||
void setDeadline();
|
||||
void expire();
|
||||
void stdchrono();
|
||||
};
|
||||
|
||||
void tst_QDeadlineTimer::initTestCase_data()
|
||||
{
|
||||
qRegisterMetaType<Qt::TimerType>();
|
||||
QTest::addColumn<Qt::TimerType>("timerType");
|
||||
QTest::newRow("precise") << Qt::PreciseTimer;
|
||||
QTest::newRow("coarse") << Qt::CoarseTimer;
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::basics()
|
||||
{
|
||||
QDeadlineTimer deadline;
|
||||
QCOMPARE(deadline.timerType(), Qt::CoarseTimer);
|
||||
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
deadline = QDeadlineTimer(timerType);
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline, QDeadlineTimer(timerType));
|
||||
QVERIFY(!(deadline != QDeadlineTimer(timerType)));
|
||||
QVERIFY(!(deadline < QDeadlineTimer()));
|
||||
QVERIFY(deadline <= QDeadlineTimer());
|
||||
QVERIFY(deadline >= QDeadlineTimer());
|
||||
QVERIFY(!(deadline > QDeadlineTimer()));
|
||||
QVERIFY(!(deadline < deadline));
|
||||
QVERIFY(deadline <= deadline);
|
||||
QVERIFY(deadline >= deadline);
|
||||
QVERIFY(!(deadline > deadline));
|
||||
|
||||
// should have expired, but we may be running too early after boot
|
||||
QTRY_VERIFY_WITH_TIMEOUT(deadline.hasExpired(), 100);
|
||||
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QCOMPARE(deadline.deadline(), qint64(0));
|
||||
QCOMPARE(deadline.deadlineNSecs(), qint64(0));
|
||||
|
||||
deadline.setRemainingTime(0, timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseRemainingTime(0, 0, timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setDeadline(0, timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QCOMPARE(deadline.deadline(), qint64(0));
|
||||
QCOMPARE(deadline.deadlineNSecs(), qint64(0));
|
||||
|
||||
deadline.setPreciseDeadline(0, 0, timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QCOMPARE(deadline.deadline(), qint64(0));
|
||||
QCOMPARE(deadline.deadlineNSecs(), qint64(0));
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::foreverness()
|
||||
{
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
// we don't check whether timerType() is our type since it's possible it detects it's forever
|
||||
|
||||
QDeadlineTimer deadline = QDeadlineTimer::Forever;
|
||||
QCOMPARE(deadline.timerType(), Qt::CoarseTimer);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline = QDeadlineTimer(-1, timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setRemainingTime(-1, timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseRemainingTime(-1, 0, timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseRemainingTime(-1, -1, timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setDeadline(std::numeric_limits<qint64>::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseDeadline(std::numeric_limits<qint64>::max(), 0, timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QCOMPARE(deadline.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
|
||||
QCOMPARE(deadline, deadline);
|
||||
QVERIFY(!(deadline < deadline));
|
||||
QVERIFY(deadline <= deadline);
|
||||
QVERIFY(deadline >= deadline);
|
||||
QVERIFY(!(deadline > deadline));
|
||||
|
||||
// adding to forever must still be forever
|
||||
QDeadlineTimer deadline2 = deadline + 1;
|
||||
QVERIFY(deadline2.isForever());
|
||||
QVERIFY(!deadline2.hasExpired());
|
||||
QCOMPARE(deadline2.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline2.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline2.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline2.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline2.timerType(), deadline.timerType());
|
||||
|
||||
QCOMPARE(deadline2 - deadline, qint64(0));
|
||||
QCOMPARE(deadline2, deadline);
|
||||
QVERIFY(!(deadline2 < deadline));
|
||||
QVERIFY(deadline2 <= deadline);
|
||||
QVERIFY(deadline2 >= deadline);
|
||||
QVERIFY(!(deadline2 > deadline));
|
||||
|
||||
// subtracting from forever is *also* forever
|
||||
deadline2 = deadline - 1;
|
||||
QVERIFY(deadline2.isForever());
|
||||
QVERIFY(!deadline2.hasExpired());
|
||||
QCOMPARE(deadline2.remainingTime(), qint64(-1));
|
||||
QCOMPARE(deadline2.remainingTimeNSecs(), qint64(-1));
|
||||
QCOMPARE(deadline2.deadline(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline2.deadlineNSecs(), std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline2.timerType(), deadline.timerType());
|
||||
|
||||
QCOMPARE(deadline2 - deadline, qint64(0));
|
||||
QCOMPARE(deadline2, deadline);
|
||||
QVERIFY(!(deadline2 < deadline));
|
||||
QVERIFY(deadline2 <= deadline);
|
||||
QVERIFY(deadline2 >= deadline);
|
||||
QVERIFY(!(deadline2 > deadline));
|
||||
|
||||
// compare and order against a default-constructed object
|
||||
QDeadlineTimer expired;
|
||||
QVERIFY(!(deadline == expired));
|
||||
QVERIFY(deadline != expired);
|
||||
QVERIFY(!(deadline < expired));
|
||||
QVERIFY(!(deadline <= expired));
|
||||
QVERIFY(deadline >= expired);
|
||||
QVERIFY(deadline > expired);
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::current()
|
||||
{
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
auto deadline = QDeadlineTimer::current(timerType);
|
||||
QVERIFY(deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
// subtracting from current should be "more expired"
|
||||
QDeadlineTimer earlierDeadline = deadline - 1;
|
||||
QVERIFY(earlierDeadline.hasExpired());
|
||||
QVERIFY(!earlierDeadline.isForever());
|
||||
QCOMPARE(earlierDeadline.timerType(), timerType);
|
||||
QCOMPARE(earlierDeadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(earlierDeadline.remainingTimeNSecs(), qint64(0));
|
||||
QVERIFY(earlierDeadline.deadline() != 0);
|
||||
QVERIFY(earlierDeadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(earlierDeadline.deadlineNSecs() != 0);
|
||||
QVERIFY(earlierDeadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(earlierDeadline.deadline(), deadline.deadline() - 1);
|
||||
QCOMPARE(earlierDeadline.deadlineNSecs(), deadline.deadlineNSecs() - 1000*1000);
|
||||
|
||||
QCOMPARE(earlierDeadline - deadline, qint64(-1));
|
||||
QVERIFY(earlierDeadline != deadline);
|
||||
QVERIFY(earlierDeadline < deadline);
|
||||
QVERIFY(earlierDeadline <= deadline);
|
||||
QVERIFY(!(earlierDeadline >= deadline));
|
||||
QVERIFY(!(earlierDeadline > deadline));
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::deadlines()
|
||||
{
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
|
||||
QDeadlineTimer deadline(4 * minResolution, timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (3 * minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= (4 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setRemainingTime(4 * minResolution, timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (3 * minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= (4 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseRemainingTime(0, 4000000 * minResolution, timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (3 * minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= (4 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
deadline.setPreciseRemainingTime(1, 0, timerType); // 1 sec
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (1000 - minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= 1000);
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (1000 - minResolution)*1000*1000);
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (1000*1000*1000));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
|
||||
// adding to a future deadline must still be further in the future
|
||||
QDeadlineTimer laterDeadline = deadline + 1;
|
||||
QVERIFY(!laterDeadline.hasExpired());
|
||||
QVERIFY(!laterDeadline.isForever());
|
||||
QCOMPARE(laterDeadline.timerType(), timerType);
|
||||
QVERIFY(laterDeadline.remainingTime() > (1000 - minResolution));
|
||||
QVERIFY(laterDeadline.remainingTime() <= 1001);
|
||||
QVERIFY(laterDeadline.remainingTimeNSecs() > (1001 - minResolution)*1000*1000);
|
||||
QVERIFY(laterDeadline.remainingTimeNSecs() <= (1001*1000*1000));
|
||||
QVERIFY(laterDeadline.deadline() != 0);
|
||||
QVERIFY(laterDeadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(laterDeadline.deadlineNSecs() != 0);
|
||||
QVERIFY(laterDeadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(laterDeadline.deadline(), deadline.deadline() + 1);
|
||||
QCOMPARE(laterDeadline.deadlineNSecs(), deadline.deadlineNSecs() + 1000*1000);
|
||||
|
||||
QCOMPARE(laterDeadline - deadline, qint64(1));
|
||||
QVERIFY(laterDeadline != deadline);
|
||||
QVERIFY(!(laterDeadline < deadline));
|
||||
QVERIFY(!(laterDeadline <= deadline));
|
||||
QVERIFY(laterDeadline >= deadline);
|
||||
QVERIFY(laterDeadline > deadline);
|
||||
|
||||
// compare and order against a default-constructed object
|
||||
QDeadlineTimer expired;
|
||||
QVERIFY(!(deadline == expired));
|
||||
QVERIFY(deadline != expired);
|
||||
QVERIFY(!(deadline < expired));
|
||||
QVERIFY(!(deadline <= expired));
|
||||
QVERIFY(deadline >= expired);
|
||||
QVERIFY(deadline > expired);
|
||||
|
||||
// compare and order against a forever deadline
|
||||
QDeadlineTimer forever_(QDeadlineTimer::Forever);
|
||||
QVERIFY(!(deadline == forever_));
|
||||
QVERIFY(deadline != forever_);
|
||||
QVERIFY(deadline < forever_);
|
||||
QVERIFY(deadline <= forever_);
|
||||
QVERIFY(!(deadline >= forever_));
|
||||
QVERIFY(!(deadline > forever_));
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::setDeadline()
|
||||
{
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
auto now = QDeadlineTimer::current(timerType);
|
||||
QDeadlineTimer deadline;
|
||||
|
||||
deadline.setDeadline(now.deadline(), timerType);
|
||||
QVERIFY(deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QCOMPARE(deadline.deadline(), now.deadline());
|
||||
// don't check deadlineNSecs!
|
||||
|
||||
deadline.setPreciseDeadline(now.deadlineNSecs() / (1000 * 1000 * 1000),
|
||||
now.deadlineNSecs() % (1000 * 1000 * 1000), timerType);
|
||||
QVERIFY(deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QCOMPARE(deadline.deadline(), now.deadline());
|
||||
QCOMPARE(deadline.deadlineNSecs(), now.deadlineNSecs());
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline.setDeadline(now.deadline() + 4 * minResolution, timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (3 * minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= (4 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
|
||||
QCOMPARE(deadline.deadline(), now.deadline() + 4 * minResolution); // yes, it's exact
|
||||
// don't check deadlineNSecs!
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
qint64 nsec = now.deadlineNSecs() + 4000000 * minResolution;
|
||||
deadline.setPreciseDeadline(nsec / (1000 * 1000 * 1000),
|
||||
nsec % (1000 * 1000 * 1000), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTime() > (3 * minResolution));
|
||||
QVERIFY(deadline.remainingTime() <= (4 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
|
||||
QCOMPARE(deadline.deadline(), nsec / (1000 * 1000));
|
||||
QCOMPARE(deadline.deadlineNSecs(), nsec);
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::expire()
|
||||
{
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
|
||||
QDeadlineTimer deadline(minResolution, timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
|
||||
qint64 previousDeadline = deadline.deadlineNSecs();
|
||||
|
||||
QTest::qSleep(2 * minResolution);
|
||||
|
||||
QCOMPARE(deadline.remainingTime(), qint64(0));
|
||||
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
|
||||
QVERIFY(deadline.deadline() != 0);
|
||||
QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
|
||||
QVERIFY(deadline.deadlineNSecs() != 0);
|
||||
QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
|
||||
QCOMPARE(deadline.deadlineNSecs(), previousDeadline);
|
||||
}
|
||||
|
||||
void tst_QDeadlineTimer::stdchrono()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
QSKIP("std::chrono not found on this system");
|
||||
#else
|
||||
using namespace std::chrono;
|
||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||
|
||||
// create some forevers
|
||||
QDeadlineTimer deadline = milliseconds::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline = milliseconds::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline.setRemainingTime(milliseconds::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
deadline = nanoseconds::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline.setRemainingTime(nanoseconds::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
deadline = hours::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline.setRemainingTime(hours::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
|
||||
deadline = time_point<system_clock>::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline.setDeadline(time_point<system_clock>::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
deadline = time_point<steady_clock>::max();
|
||||
QVERIFY(deadline.isForever());
|
||||
deadline.setDeadline(time_point<steady_clock>::max(), timerType);
|
||||
QVERIFY(deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
|
||||
QVERIFY(deadline == time_point<steady_clock>::max());
|
||||
QVERIFY(deadline == time_point<system_clock>::max());
|
||||
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::max());
|
||||
|
||||
// make it expired
|
||||
deadline = time_point<system_clock>();
|
||||
QVERIFY(deadline.hasExpired());
|
||||
deadline.setDeadline(time_point<system_clock>(), timerType);
|
||||
QVERIFY(deadline.hasExpired());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
deadline = time_point<steady_clock>();
|
||||
QVERIFY(deadline.hasExpired());
|
||||
deadline.setDeadline(time_point<steady_clock>(), timerType);
|
||||
QVERIFY(deadline.hasExpired());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
|
||||
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero());
|
||||
|
||||
auto steady_before = steady_clock::now();
|
||||
auto system_before = system_clock::now();
|
||||
|
||||
QTest::qSleep(minResolution);
|
||||
auto now = QDeadlineTimer::current(timerType);
|
||||
QTest::qSleep(minResolution);
|
||||
|
||||
auto steady_after = steady_clock::now();
|
||||
auto system_after = system_clock::now();
|
||||
|
||||
{
|
||||
auto diff = duration_cast<milliseconds>(steady_after - now.deadline<steady_clock>());
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_after(steady_after, timerType);
|
||||
QVERIFY2(now < dt_after,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
|
||||
|
||||
diff = duration_cast<milliseconds>(now.deadline<steady_clock>() - steady_before);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_before(steady_before, timerType);
|
||||
QVERIFY2(now > dt_before,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
|
||||
}
|
||||
{
|
||||
auto diff = duration_cast<milliseconds>(system_after - now.deadline<system_clock>());
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_after(system_after, timerType);
|
||||
QVERIFY2(now < dt_after,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
|
||||
|
||||
diff = duration_cast<milliseconds>(now.deadline<system_clock>() - system_before);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_before(system_before, timerType);
|
||||
QVERIFY2(now > dt_before,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
|
||||
}
|
||||
|
||||
// make it regular
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline.setRemainingTime(milliseconds(4 * minResolution), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > milliseconds(3 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() < milliseconds(5 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > nanoseconds(3000000 * minResolution));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() < nanoseconds(5000000 * minResolution));
|
||||
QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + milliseconds(3 * minResolution)));
|
||||
QVERIFY(deadline.deadline<steady_clock>() < (steady_clock::now() + milliseconds(5 * minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + milliseconds(3 * minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() < (system_clock::now() + milliseconds(5 * minResolution)));
|
||||
if (timerType == Qt::CoarseTimer) {
|
||||
QVERIFY(deadline > (now + milliseconds(3 * minResolution)));
|
||||
QVERIFY(deadline < (now + milliseconds(5 * minResolution)));
|
||||
QVERIFY(deadline > (now + nanoseconds(3000000 * minResolution)));
|
||||
QVERIFY(deadline < (now + nanoseconds(5000000 * minResolution)));
|
||||
QVERIFY(deadline > milliseconds(3 * minResolution));
|
||||
QVERIFY(deadline < milliseconds(5 * minResolution));
|
||||
QVERIFY(deadline > nanoseconds(3000000 * minResolution));
|
||||
QVERIFY(deadline < nanoseconds(5000000 * minResolution));
|
||||
QVERIFY(deadline >= steady_clock::now());
|
||||
QVERIFY(deadline >= system_clock::now());
|
||||
}
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline = QDeadlineTimer(seconds(1), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
|
||||
QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
if (timerType == Qt::CoarseTimer) {
|
||||
QVERIFY(deadline > (seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline <= seconds(1));
|
||||
}
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline.setRemainingTime(hours(1), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > (hours(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() <= hours(1));
|
||||
QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + hours(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + hours(1) + milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + hours(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + hours(1) + milliseconds(minResolution)));
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline.setDeadline(system_clock::now() + seconds(1), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
|
||||
QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
|
||||
now = QDeadlineTimer::current(timerType);
|
||||
deadline.setDeadline(steady_clock::now() + seconds(1), timerType);
|
||||
QVERIFY(!deadline.hasExpired());
|
||||
QVERIFY(!deadline.isForever());
|
||||
QCOMPARE(deadline.timerType(), timerType);
|
||||
QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
|
||||
QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
|
||||
QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDeadlineTimer)
|
||||
|
||||
#include "tst_qdeadlinetimer.moc"
|
Loading…
x
Reference in New Issue
Block a user