From 275f182872fa2671da9445ba6295f50f2c283ae6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 14 Dec 2015 09:15:16 +0100 Subject: 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 --- src/corelib/kernel/qfunctions_winrt.h | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src/corelib/kernel/qfunctions_winrt.h') diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h index ee4e050793..dc1cbe0ade 100644 --- a/src/corelib/kernel/qfunctions_winrt.h +++ b/src/corelib/kernel/qfunctions_winrt.h @@ -40,6 +40,7 @@ #include #include +#include #include // Convenience macros for handling HRESULT values @@ -160,7 +161,7 @@ enum AwaitStyle }; template -static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle) +static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle, uint timeout) { Microsoft::WRL::ComPtr asyncInfo; HRESULT hr = asyncOp.As(&asyncInfo); @@ -168,22 +169,34 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &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 &asyncOp, Awai } template -static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle = YieldThread) +static inline HRESULT await(const Microsoft::WRL::ComPtr &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 &asyncOp, AwaitStyle } template -static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread) +static inline HRESULT await(const Microsoft::WRL::ComPtr &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; -- cgit v1.2.3