diff options
author | Andrew Knight <andrew.knight@digia.com> | 2014-01-05 12:41:16 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-07 10:55:54 +0100 |
commit | 9b19a69c89c07b02ab631c1ccfd4d89013b6ec45 (patch) | |
tree | 064473ca07e0876cf81c86741ba1e45091e67921 /src/corelib | |
parent | 1f31c6c6b1f4b37806aa5c1c426efb31ac78ed5e (diff) |
WinRT: Clean up core event dispatcher
- Move private classes in the .cpp file (they aren't needed outside)
- Conform to Qt style, such as includes and braces
- Use ComPtr where appropriate
- Use foreach where appropriate
- Remove non-functional wake/interrupt leftovers
- Remove redundant timer list
- Make the timer callback a static method, so it won't crash if it
gets called on shutdown
Task-number: QTBUG-35945
Change-Id: I5426fba2735e908a04ea60287f9936f5abde6644
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_winrt.cpp | 166 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_winrt_p.h | 59 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 2 |
3 files changed, 88 insertions, 139 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index daef8428e1..8639e925cd 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -41,13 +41,15 @@ #include "qeventdispatcher_winrt_p.h" -#include "qelapsedtimer.h" -#include "qcoreapplication.h" -#include "qthread.h" +#include <QtCore/QCoreApplication> +#include <QtCore/QThread> +#include <QtCore/QHash> #include <private/qcoreapplication_p.h> #include <private/qthread_p.h> +#include <private/qabstracteventdispatcher_p.h> +#include <wrl.h> #include <windows.foundation.h> #include <windows.system.threading.h> using namespace Microsoft::WRL; @@ -57,6 +59,58 @@ using namespace ABI::Windows::Foundation; QT_BEGIN_NAMESPACE +class QZeroTimerEvent : public QTimerEvent +{ +public: + explicit inline QZeroTimerEvent(int timerId) + : QTimerEvent(timerId) + { t = QEvent::ZeroTimerEvent; } +}; + +struct WinRTTimerInfo // internal timer info +{ + WinRTTimerInfo() : timer(0) {} + + int id; + int interval; + Qt::TimerType timerType; + quint64 timeout; // - when to actually fire + QObject *obj; // - object to receive events + bool inTimerEvent; + ComPtr<IThreadPoolTimer> timer; +}; + +class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate +{ + Q_DECLARE_PUBLIC(QEventDispatcherWinRT) + +public: + QEventDispatcherWinRTPrivate(); + ~QEventDispatcherWinRTPrivate(); + + void registerTimer(WinRTTimerInfo *t); + void unregisterTimer(WinRTTimerInfo *t); + void sendTimerEvent(int timerId); + + +private: + static HRESULT timerExpiredCallback(ABI::Windows::System::Threading::IThreadPoolTimer *source); + static int idForTimer(IThreadPoolTimer *timer) + { + QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher(); + if (!eventDispatcher) + return -1; + if (QEventDispatcherWinRTPrivate *that = static_cast<QEventDispatcherWinRTPrivate *>(get(eventDispatcher))) + return that->timerIds.value(timer, -1); + return -1; + } + + QHash<int, WinRTTimerInfo*> timerDict; + QHash<IThreadPoolTimer *, int> timerIds; + + ComPtr<IThreadPoolTimerStatics> timerFactory; +}; + QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent) { @@ -110,19 +164,15 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy } Q_D(QEventDispatcherWinRT); - WinRTTimerInfo *t = new WinRTTimerInfo(); - t->dispatcher = this; - t->timerId = timerId; + t->id = timerId; t->interval = interval; - t->timeout = interval; t->timerType = timerType; t->obj = object; t->inTimerEvent = false; d->registerTimer(t); - d->timerVec.append(t); // store in timer vector - d->timerDict.insert(t->timerId, t); // store timers in dict + d->timerDict.insert(t->id, t); } bool QEventDispatcherWinRT::unregisterTimer(int timerId) @@ -137,17 +187,11 @@ bool QEventDispatcherWinRT::unregisterTimer(int timerId) } Q_D(QEventDispatcherWinRT); - if (d->timerVec.isEmpty() || timerId <= 0) - return false; WinRTTimerInfo *t = d->timerDict.value(timerId); if (!t) return false; - if (t->timer) - d->threadPoolTimerDict.remove(t->timer); - d->timerDict.remove(t->timerId); - d->timerVec.removeAll(t); d->unregisterTimer(t); return true; } @@ -165,19 +209,9 @@ bool QEventDispatcherWinRT::unregisterTimers(QObject *object) } Q_D(QEventDispatcherWinRT); - if (d->timerVec.isEmpty()) - return false; - register WinRTTimerInfo *t; - for (int i = 0; i < d->timerVec.size(); i++) { - t = d->timerVec.at(i); - if (t && t->obj == object) { // object found - if (t->timer) - d->threadPoolTimerDict.remove(t->timer); - d->timerDict.remove(t->timerId); - d->timerVec.removeAt(i); + foreach (WinRTTimerInfo *t, d->timerDict) { + if (t->obj == object) d->unregisterTimer(t); - --i; - } } return true; } @@ -191,10 +225,9 @@ QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTime Q_D(const QEventDispatcherWinRT); QList<TimerInfo> list; - for (int i = 0; i < d->timerVec.size(); ++i) { - const WinRTTimerInfo *t = d->timerVec.at(i); - if (t && t->obj == object) - list << TimerInfo(t->timerId, t->interval, t->timerType); + foreach (const WinRTTimerInfo *t, d->timerDict) { + if (t->obj == object) + list.append(TimerInfo(t->id, t->interval, t->timerType)); } return list; } @@ -222,45 +255,28 @@ int QEventDispatcherWinRT::remainingTime(int timerId) #endif Q_D(QEventDispatcherWinRT); - - if (d->timerVec.isEmpty()) - return -1; - - quint64 currentTime = qt_msectime(); - - register WinRTTimerInfo *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; - } + if (WinRTTimerInfo *t = d->timerDict.value(timerId)) { + const quint64 currentTime = qt_msectime(); + if (currentTime < t->timeout) { + // time to wait + return t->timeout - currentTime; + } else { + return 0; } } #ifndef QT_NO_DEBUG qWarning("QEventDispatcherWinRT::remainingTime: timer id %d not found", timerId); #endif - return -1; } void QEventDispatcherWinRT::wakeUp() { - Q_D(QEventDispatcherWinRT); - if (d->wakeUps.testAndSetAcquire(0, 1)) { - // ###TODO: is there any thing to wake up? - } } void QEventDispatcherWinRT::interrupt() { - Q_D(QEventDispatcherWinRT); - d->interrupt = true; - wakeUp(); } void QEventDispatcherWinRT::flush() @@ -274,13 +290,10 @@ void QEventDispatcherWinRT::startingUp() void QEventDispatcherWinRT::closingDown() { Q_D(QEventDispatcherWinRT); - - // clean up any timers - for (int i = 0; i < d->timerVec.count(); ++i) - d->unregisterTimer(d->timerVec.at(i)); - d->timerVec.clear(); + foreach (WinRTTimerInfo *t, d->timerDict) + d->unregisterTimer(t); d->timerDict.clear(); - d->threadPoolTimerDict.clear(); + d->timerIds.clear(); } bool QEventDispatcherWinRT::event(QEvent *e) @@ -314,8 +327,6 @@ bool QEventDispatcherWinRT::event(QEvent *e) } QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate() - : interrupt(false) - , timerFactory(0) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory); @@ -325,8 +336,6 @@ QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate() QEventDispatcherWinRTPrivate::~QEventDispatcherWinRTPrivate() { - if (timerFactory) - timerFactory->Release(); CoUninitialize(); } @@ -334,22 +343,22 @@ void QEventDispatcherWinRTPrivate::registerTimer(WinRTTimerInfo *t) { Q_Q(QEventDispatcherWinRT); - int ok = 0; + bool ok = false; uint interval = t->interval; if (interval == 0u) { // optimization for single-shot-zero-timer - QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId)); - ok = 1; + QCoreApplication::postEvent(q, new QZeroTimerEvent(t->id)); + ok = true; } else { TimeSpan period; period.Duration = interval * 10000; // TimeSpan is based on 100-nanosecond units ok = SUCCEEDED(timerFactory->CreatePeriodicTimer( - Callback<ITimerElapsedHandler>(this, &QEventDispatcherWinRTPrivate::timerExpiredCallback).Get(), period, &t->timer)); + Callback<ITimerElapsedHandler>(&QEventDispatcherWinRTPrivate::timerExpiredCallback).Get(), period, &t->timer)); if (ok) - threadPoolTimerDict.insert(t->timer, t); + timerIds.insert(t->timer.Get(), t->id); } t->timeout = qt_msectime() + interval; - if (ok == 0) + if (!ok) qErrnoWarning("QEventDispatcherWinRT::registerTimer: Failed to create a timer"); } @@ -357,10 +366,10 @@ void QEventDispatcherWinRTPrivate::unregisterTimer(WinRTTimerInfo *t) { if (t->timer) { t->timer->Cancel(); - t->timer->Release(); + timerIds.remove(t->timer.Get()); } + timerDict.remove(t->id); delete t; - t = 0; } void QEventDispatcherWinRTPrivate::sendTimerEvent(int timerId) @@ -370,22 +379,21 @@ void QEventDispatcherWinRTPrivate::sendTimerEvent(int timerId) // send event, but don't allow it to recurse t->inTimerEvent = true; - QTimerEvent e(t->timerId); + QTimerEvent e(t->id); QCoreApplication::sendEvent(t->obj, &e); // timer could have been removed t = timerDict.value(timerId); - if (t) { + if (t) t->inTimerEvent = false; - } } } HRESULT QEventDispatcherWinRTPrivate::timerExpiredCallback(IThreadPoolTimer *source) { - register WinRTTimerInfo *t = threadPoolTimerDict.value(source); - if (t) - QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId)); + int timerId = idForTimer(source); + if (timerId > 0) + QCoreApplication::postEvent(QCoreApplication::eventDispatcher(), new QTimerEvent(timerId)); else qWarning("QEventDispatcherWinRT::timerExpiredCallback: Could not find timer %d in timer list", source); return S_OK; diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h index c5bd39c2a3..0631b2ea33 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt_p.h +++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h @@ -55,21 +55,8 @@ // #include "QtCore/qabstracteventdispatcher.h" -#include "private/qabstracteventdispatcher_p.h" #include <qt_windows.h> -#include <wrl.h> - -namespace ABI { - namespace Windows { - namespace System { - namespace Threading { - struct IThreadPoolTimer; - struct IThreadPoolTimerStatics; - } - } - } -} QT_BEGIN_NAMESPACE @@ -112,56 +99,10 @@ public: protected: QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent = 0); - bool event(QEvent *); int activateTimers(); }; -struct WinRTTimerInfo // internal timer info -{ - WinRTTimerInfo() : timer(0) {} - - QObject *dispatcher; - int timerId; - int interval; - Qt::TimerType timerType; - quint64 timeout; // - when to actually fire - QObject *obj; // - object to receive events - bool inTimerEvent; - ABI::Windows::System::Threading::IThreadPoolTimer *timer; -}; - -class QZeroTimerEvent : public QTimerEvent -{ -public: - explicit inline QZeroTimerEvent(int timerId) - : QTimerEvent(timerId) - { t = QEvent::ZeroTimerEvent; } -}; - -class Q_CORE_EXPORT QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate -{ - Q_DECLARE_PUBLIC(QEventDispatcherWinRT) - -public: - QEventDispatcherWinRTPrivate(); - ~QEventDispatcherWinRTPrivate(); - - QList<WinRTTimerInfo*> timerVec; - QHash<int, WinRTTimerInfo*> timerDict; - QHash<ABI::Windows::System::Threading::IThreadPoolTimer*, WinRTTimerInfo*> threadPoolTimerDict; - - void registerTimer(WinRTTimerInfo *t); - void unregisterTimer(WinRTTimerInfo *t); - void sendTimerEvent(int timerId); - HRESULT timerExpiredCallback(ABI::Windows::System::Threading::IThreadPoolTimer *source); - - QAtomicInt wakeUps; - bool interrupt; - - ABI::Windows::System::Threading::IThreadPoolTimerStatics *timerFactory; -}; - QT_END_NAMESPACE #endif // QEVENTDISPATCHER_WINRT_P_H diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 28e13910d9..2c3ff879e4 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -55,7 +55,7 @@ #include <private/qcoreapplication_p.h> #ifdef Q_OS_WINRT -#include "private/qeventdispatcher_winrt_p.h" +#include <private/qeventdispatcher_winrt_p.h> #else #include <private/qeventdispatcher_win_p.h> #endif |