diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-09-22 17:54:40 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-10-01 18:03:29 +0200 |
commit | 1f86957f1dd14cc538e7ad9ffee4eb63001af407 (patch) | |
tree | bda02afb1b52980a3a2114bbd57071256cdd7ed1 /src/corelib/kernel | |
parent | 0acada9c7b6fb6a96145484da011aeec3191a35a (diff) |
QWinRtFunctions::await() - introduce early exit condition
The await() method waits for the result of async operation in a
non-blocking way (triggering processEvent periodically).
It means that during this wait some other things might happen, and
there would be no reason to wait for the end of the operation execution.
This patch implements an additional parameter - a function that specifies
a condition for an early return. When this function returns true, the
await() method returns with E_ABORT, which makes it possible to
distinguish it from timer expiration.
Task-number: QTBUG-96057
Pick-to: 6.2 5.15
Change-Id: Ide73d768b7cbb3a35be7160ce7555aeb2dca5235
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qfunctions_winrt_p.h | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/corelib/kernel/qfunctions_winrt_p.h b/src/corelib/kernel/qfunctions_winrt_p.h index d98571906e..8db94c124b 100644 --- a/src/corelib/kernel/qfunctions_winrt_p.h +++ b/src/corelib/kernel/qfunctions_winrt_p.h @@ -101,8 +101,11 @@ enum AwaitStyle ProcessMainThreadEvents = 2 }; -template <typename T> -static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle, uint timeout) +using EarlyExitConditionFunction = std::function<bool(void)>; + +template<typename T> +static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle, + uint timeout, EarlyExitConditionFunction func) { Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo; HRESULT hr = asyncOp.As(&asyncInfo); @@ -117,6 +120,8 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, Awai case ProcessMainThreadEvents: while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) { QCoreApplication::processEvents(); + if (func && func()) + return E_ABORT; if (timeout && t.hasExpired(timeout)) return HRESULT_FROM_WIN32(ERROR_TIMEOUT); } @@ -125,6 +130,8 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, Awai if (QAbstractEventDispatcher *dispatcher = QThread::currentThread()->eventDispatcher()) { while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) { dispatcher->processEvents(QEventLoop::AllEvents); + if (func && func()) + return E_ABORT; if (timeout && t.hasExpired(timeout)) return HRESULT_FROM_WIN32(ERROR_TIMEOUT); } @@ -155,20 +162,24 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, Awai return hr; } -template <typename T> -static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle = YieldThread, uint timeout = 0) +template<typename T> +static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, + AwaitStyle awaitStyle = YieldThread, uint timeout = 0, + EarlyExitConditionFunction func = nullptr) { - HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout); + HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func); if (FAILED(hr)) return hr; return asyncOp->GetResults(); } -template <typename T, typename U> -static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread, uint timeout = 0) +template<typename T, typename U> +static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results, + AwaitStyle awaitStyle = YieldThread, uint timeout = 0, + EarlyExitConditionFunction func = nullptr) { - HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout); + HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func); if (FAILED(hr)) return hr; |