winrt: Added timeout to await function

Instead of using a "custom wait function" in cases,
where a timeout is needed (like in qhostinfo_winrt.cpp)
we should have the timeout as part of our await
function.

By having one common place to handle this, we can avoid
unnecessary warnings, that might be caused by custom
functions. The current implementation in qhostinfo
for example causes at least 1 "originate error"
exception per call.

Change-Id: I7b6cfdfd861af2b0d271465eecaefe4a93e3109b
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
bb10
Oliver Wolff 2015-12-14 09:15:16 +01:00
parent 452a27e1f0
commit 275f182872
1 changed files with 21 additions and 8 deletions

View File

@ -40,6 +40,7 @@
#include <QtCore/QThread>
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QElapsedTimer>
#include <QtCore/qt_windows.h>
// Convenience macros for handling HRESULT values
@ -160,7 +161,7 @@ enum AwaitStyle
};
template <typename T>
static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle)
static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle, uint timeout)
{
Microsoft::WRL::ComPtr<IAsyncInfo> asyncInfo;
HRESULT hr = asyncOp.As(&asyncInfo);
@ -168,22 +169,34 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, Awai
return hr;
AsyncStatus status;
QElapsedTimer t;
if (timeout)
t.start();
switch (awaitStyle) {
case ProcessMainThreadEvents:
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started)
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) {
QCoreApplication::processEvents();
if (timeout && t.hasExpired(timeout))
return ERROR_TIMEOUT;
}
break;
case ProcessThreadEvents:
if (QAbstractEventDispatcher *dispatcher = QThread::currentThread()->eventDispatcher()) {
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started)
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) {
dispatcher->processEvents(QEventLoop::AllEvents);
if (timeout && t.hasExpired(timeout))
return ERROR_TIMEOUT;
}
break;
}
// fall through
default:
case YieldThread:
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started)
while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) {
QThread::yieldCurrentThread();
if (timeout && t.hasExpired(timeout))
return ERROR_TIMEOUT;
}
break;
}
@ -199,9 +212,9 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, Awai
}
template <typename T>
static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle = YieldThread)
static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle = YieldThread, uint timeout = 0)
{
HRESULT hr = _await_impl(asyncOp, awaitStyle);
HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout);
if (FAILED(hr))
return hr;
@ -209,9 +222,9 @@ static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle
}
template <typename T, typename U>
static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread)
static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread, uint timeout = 0)
{
HRESULT hr = _await_impl(asyncOp, awaitStyle);
HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout);
if (FAILED(hr))
return hr;