From ed7894dd77962fb4e5fa58706bd99f69a3f333c3 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 25 Jul 2014 23:21:07 +0300 Subject: winrt: Handle dispatcher thread change If the calling thread changes when processing events, the dispatcher will no longer have thread access and event processing will fail. This can e.g. prevent new threads from being created. To remedy this, the dispatcher object is re-fetched if the thread is changed. Change-Id: I519cff521f9b84211db3f28a7a28b532de44a6a4 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 39 ++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'src/corelib/kernel/qeventdispatcher_winrt.cpp') diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index 91a97885ee..c601b4cea1 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -133,6 +133,7 @@ private: ComPtr timerFactory; ComPtr coreDispatcher; + QPointer thread; bool interrupt; }; @@ -140,24 +141,6 @@ private: QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent) { - Q_D(QEventDispatcherWinRT); - - // Obtain the WinRT Application, view, and window - ComPtr application; - HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), - IID_PPV_ARGS(&application)); - RETURN_VOID_IF_FAILED("Failed to activate the application factory"); - - ComPtr view; - hr = application->get_MainView(&view); - RETURN_VOID_IF_FAILED("Failed to get the main view"); - - ComPtr window; - hr = view->get_CoreWindow(&window); - RETURN_VOID_IF_FAILED("Failed to get the core window"); - - hr = window->get_Dispatcher(&d->coreDispatcher); - RETURN_VOID_IF_FAILED("Failed to get the core dispatcher"); } QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent) @@ -172,6 +155,26 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherWinRT); + if (d->thread != QThread::currentThread()) { + ComPtr application; + HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + IID_PPV_ARGS(&application)); + RETURN_FALSE_IF_FAILED("Failed to get the application factory"); + + ComPtr view; + hr = application->get_MainView(&view); + RETURN_FALSE_IF_FAILED("Failed to get the main view"); + + ComPtr window; + hr = view->get_CoreWindow(&window); + RETURN_FALSE_IF_FAILED("Failed to get the core window"); + + hr = window->get_Dispatcher(&d->coreDispatcher); + RETURN_FALSE_IF_FAILED("Failed to get the core dispatcher"); + + d->thread = QThread::currentThread(); + } + bool didProcess = false; forever { // Process native events -- cgit v1.2.3