summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp10
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp13
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp13
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp39
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h4
-rw-r--r--src/corelib/kernel/qtimer.cpp19
-rw-r--r--src/corelib/kernel/qtimer.h3
-rw-r--r--src/corelib/kernel/qtimerinfo_unix.cpp31
-rw-r--r--src/corelib/kernel/qtimerinfo_unix_p.h2
-rw-r--r--src/corelib/tools/qelapsedtimer_win.cpp5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm13
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp1
-rw-r--r--tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp17
-rw-r--r--tests/auto/corelib/thread/qthread/tst_qthread.cpp1
-rw-r--r--tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp1
-rw-r--r--tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp1
20 files changed, 181 insertions, 0 deletions
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index b98f3f4a30..9c025d6d6f 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -295,6 +295,16 @@ int QAbstractEventDispatcher::registerTimer(int interval, Qt::TimerType timerTyp
\sa Qt::TimerType
*/
+/*!
+ \fn int QAbstractEventDispatcher::remainingTime(int timerId)
+
+ Returns the remaining time in milliseconds with the given \a timerId.
+ If the timer is inactive, the returned value will be -1. If the timer is
+ overdue, the returned value will be 0.
+
+ \sa Qt::TimerType
+*/
+
/*! \fn void QAbstractEventDispatcher::wakeUp()
\threadsafe
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index 76f264c3c0..96498d207d 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -93,6 +93,8 @@ public:
virtual bool unregisterTimers(QObject *object) = 0;
virtual QList<TimerInfo> registeredTimers(QObject *object) const = 0;
+ virtual int remainingTime(int timerId) = 0;
+
virtual void wakeUp() = 0;
virtual void interrupt() = 0;
virtual void flush() = 0;
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 3f272a2512..4429679e72 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -567,6 +567,19 @@ QList<QEventDispatcherGlib::TimerInfo> QEventDispatcherGlib::registeredTimers(QO
return d->timerSource->timerList.registeredTimers(object);
}
+int QEventDispatcherGlib::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherGlib::remainingTimeTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherGlib);
+ return d->timerSource->timerList.timerRemainingTime(timerId);
+}
+
void QEventDispatcherGlib::interrupt()
{
wakeUp();
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index 7bd40564b9..e230972092 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -85,6 +85,8 @@ public:
bool unregisterTimers(QObject *object);
QList<TimerInfo> registeredTimers(QObject *object) const;
+ int remainingTime(int timerId);
+
void wakeUp();
void interrupt();
void flush();
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index d5805112e9..6eb96b832c 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -628,6 +628,19 @@ bool QEventDispatcherUNIX::hasPendingEvents()
return qGlobalPostedEventsCount();
}
+int QEventDispatcherUNIX::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherUNIX::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherUNIX);
+ return d->timerList.timerRemainingTime(timerId);
+}
+
void QEventDispatcherUNIX::wakeUp()
{
Q_D(QEventDispatcherUNIX);
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index e618853e09..05ecf52dbf 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -116,6 +116,8 @@ public:
bool unregisterTimers(QObject *object);
QList<TimerInfo> registeredTimers(QObject *object) const;
+ int remainingTime(int timerId);
+
void wakeUp();
void interrupt();
void flush();
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 768fde682b..26fd6316ae 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -50,6 +50,7 @@
#include "qvarlengtharray.h"
#include "qwineventnotifier.h"
+#include "qelapsedtimer.h"
#include "qcoreapplication_p.h"
#include <private/qthread_p.h>
#include <private/qmutexpool_p.h>
@@ -532,6 +533,8 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
ok = SetTimer(internalHwnd, t->timerId, interval, 0);
}
+ t->timeout = qt_msectime() + interval;
+
if (ok == 0)
qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
}
@@ -998,6 +1001,42 @@ void QEventDispatcherWin32::activateEventNotifiers()
}
}
+int QEventDispatcherWin32::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWin32::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherWin32);
+
+ if (d->timerVec.isEmpty())
+ return -1;
+
+ quint64 currentTime = qt_msectime();
+
+ register WinTimerInfo *t;
+ for (int i=0; i<d->timerVec.size(); i++) {
+ t = d->timerVec.at(i);
+ if (t && t->timerId == timerId) { // timer found
+ if (currentTime < t->timeout) {
+ // time to wait
+ return t->timeout - currentTime;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+#ifndef QT_NO_DEBUG
+ qWarning("QEventDispatcherWin32::remainingTime: timer id %s not found", timerId);
+#endif
+
+ return -1;
+}
+
void QEventDispatcherWin32::wakeUp()
{
Q_D(QEventDispatcherWin32);
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 565f1ef4b3..e78236fd40 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -66,6 +66,7 @@ class QEventDispatcherWin32Private;
// forward declaration
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
+int qt_msectime();
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
{
@@ -94,6 +95,8 @@ public:
void unregisterEventNotifier(QWinEventNotifier *notifier);
void activateEventNotifiers();
+ int remainingTime(int timerId);
+
void wakeUp();
void interrupt();
void flush();
@@ -123,6 +126,7 @@ struct WinTimerInfo { // internal timer info
int timerId;
int interval;
Qt::TimerType timerType;
+ quint64 timeout; // - when to actually fire
QObject *obj; // - object to receive events
bool inTimerEvent;
int fastTimerId;
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index f434df177c..2131188439 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -387,6 +387,25 @@ void QTimer::setInterval(int msec)
}
/*!
+ \property QTimer::remainingTime
+ \brief the remaining time in milliseconds
+
+ Returns the timer's remaining value in milliseconds left until the timeout.
+ If the timer is inactive, the returned value will be -1. If the timer is
+ overdue, the returned value will be 0.
+
+ \sa interval
+*/
+int QTimer::remainingTime() const
+{
+ if (id != INV_TIMER) {
+ return QAbstractEventDispatcher::instance()->remainingTime(id);
+ }
+
+ return -1;
+}
+
+/*!
\property QTimer::timerType
\brief controls the accuracy of the timer
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index eff2a7bfe1..fa68676f27 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -57,6 +57,7 @@ class Q_CORE_EXPORT QTimer : public QObject
Q_OBJECT
Q_PROPERTY(bool singleShot READ isSingleShot WRITE setSingleShot)
Q_PROPERTY(int interval READ interval WRITE setInterval)
+ Q_PROPERTY(int remainingTime READ remainingTime)
Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType)
Q_PROPERTY(bool active READ isActive)
public:
@@ -69,6 +70,8 @@ public:
void setInterval(int msec);
int interval() const { return inter; }
+ int remainingTime() const;
+
void setTimerType(Qt::TimerType atype) { this->type = atype; }
Qt::TimerType timerType() const { return Qt::TimerType(type); }
diff --git a/src/corelib/kernel/qtimerinfo_unix.cpp b/src/corelib/kernel/qtimerinfo_unix.cpp
index 32e24edcf3..709338afda 100644
--- a/src/corelib/kernel/qtimerinfo_unix.cpp
+++ b/src/corelib/kernel/qtimerinfo_unix.cpp
@@ -412,6 +412,37 @@ bool QTimerInfoList::timerWait(timeval &tm)
return true;
}
+/*
+ Returns the timer's remaining time in milliseconds with the given timerId, or
+ null if there is nothing left. If the timer id is not found in the list, the
+ returned value will be -1. If the timer is overdue, the returned value will be 0.
+*/
+int QTimerInfoList::timerRemainingTime(int timerId)
+{
+ timeval currentTime = updateCurrentTime();
+ repairTimersIfNeeded();
+ timeval tm = {0, 0};
+
+ for (int i = 0; i < count(); ++i) {
+ register QTimerInfo *t = at(i);
+ if (t->id == timerId) {
+ if (currentTime < t->timeout) {
+ // time to wait
+ tm = roundToMillisecond(t->timeout - currentTime);
+ return tm.tv_sec*1000 + tm.tv_usec/1000;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+#ifndef QT_NO_DEBUG
+ qWarning("QTimerInfoList::timerRemainingTime: timer id %i not found", timerId);
+#endif
+
+ return -1;
+}
+
void QTimerInfoList::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
{
QTimerInfo *t = new QTimerInfo;
diff --git a/src/corelib/kernel/qtimerinfo_unix_p.h b/src/corelib/kernel/qtimerinfo_unix_p.h
index 4bf6b91ea6..cd431f9a4f 100644
--- a/src/corelib/kernel/qtimerinfo_unix_p.h
+++ b/src/corelib/kernel/qtimerinfo_unix_p.h
@@ -104,6 +104,8 @@ public:
bool timerWait(timeval &);
void timerInsert(QTimerInfo *);
+ int timerRemainingTime(int timerId);
+
void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
bool unregisterTimer(int timerId);
bool unregisterTimers(QObject *object);
diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp
index 8171a27ea3..51e0690e72 100644
--- a/src/corelib/tools/qelapsedtimer_win.cpp
+++ b/src/corelib/tools/qelapsedtimer_win.cpp
@@ -120,6 +120,11 @@ static quint64 getTickCount()
return val | (quint64(highdword) << 32);
}
+int qt_msectime()
+{
+ return ticksToNanoseconds(getTickCount()) / 1000000;
+}
+
QElapsedTimer::ClockType QElapsedTimer::clockType()
{
resolveLibs();
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index a4a1286fab..7fa1f0971f 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -128,6 +128,8 @@ public:
bool unregisterTimers(QObject *object);
QList<TimerInfo> registeredTimers(QObject *object) const;
+ int remainingTime(int timerId);
+
void wakeUp();
void interrupt();
void flush();
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 77cccac0b4..02722ce5bf 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -680,6 +680,19 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
return retVal;
}
+int QCocoaEventDispatcher::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QCocoaEventDispatcher::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QCocoaEventDispatcher);
+ return d->timerInfoList.timerRemainingTime(timerId);
+}
+
void QCocoaEventDispatcher::wakeUp()
{
Q_D(QCocoaEventDispatcher);
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
index 84d723ca61..29fa98b8bb 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
@@ -616,6 +616,7 @@ public:
bool unregisterTimer(int ) { return false; }
bool unregisterTimers(QObject *) { return false; }
QList<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); }
+ int remainingTime(int) { return 0; }
void wakeUp() {}
void interrupt() {}
void flush() {}
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index e8dade9387..e4ecfb6f2d 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -55,6 +55,7 @@ private slots:
void zeroTimer();
void singleShotTimeout();
void timeout();
+ void remainingTime();
void livelock_data();
void livelock();
void timerInfiniteRecursion_data();
@@ -143,6 +144,22 @@ void tst_QTimer::timeout()
QVERIFY(helper.count > oldCount);
}
+void tst_QTimer::remainingTime()
+{
+ TimerHelper helper;
+ QTimer timer;
+
+ connect(&timer, SIGNAL(timeout()), &helper, SLOT(timeout()));
+ timer.start(200);
+
+ QCOMPARE(helper.count, 0);
+
+ QTest::qWait(50);
+ QCOMPARE(helper.count, 0);
+
+ int remainingTime = timer.remainingTime();
+ QVERIFY2(qAbs(remainingTime - 150) < 50, qPrintable(QString::number(remainingTime)));
+}
void tst_QTimer::livelock_data()
{
diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
index 8eccd17376..41cfc52354 100644
--- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp
+++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
@@ -1234,6 +1234,7 @@ public:
bool unregisterTimer(int ) { return false; }
bool unregisterTimers(QObject *) { return false; }
QList<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); }
+ int remainingTime(int) { return 0; }
void wakeUp() {}
void interrupt() {}
void flush() {}
diff --git a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
index bcd703b5d1..82de653586 100644
--- a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
+++ b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
@@ -62,6 +62,7 @@ public:
void unregisterSocketNotifier(QSocketNotifier*) {}
bool unregisterTimer(int) { return false; }
bool unregisterTimers(QObject*) { return false; }
+ int remainingTime(int) { return 0; }
void wakeUp() {}
};
diff --git a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
index cb1f7feead..d3be93b715 100644
--- a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
+++ b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
@@ -62,6 +62,7 @@ public:
void unregisterSocketNotifier(QSocketNotifier*) {}
bool unregisterTimer(int) { return false; }
bool unregisterTimers(QObject*) { return false; }
+ int remainingTime(int) { return 0; }
void wakeUp() {}
};