summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-09-22 17:54:40 +0200
committerIvan Solovev <ivan.solovev@qt.io>2021-10-01 18:03:29 +0200
commit1f86957f1dd14cc538e7ad9ffee4eb63001af407 (patch)
treebda02afb1b52980a3a2114bbd57071256cdd7ed1 /src/corelib/kernel
parent0acada9c7b6fb6a96145484da011aeec3191a35a (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.h27
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;