summaryrefslogtreecommitdiffstats
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-07 11:14:37 +0200
commit5b839c103de980e0b98b01bd067721f2406f4e33 (patch)
tree491cf3706b9b0c06f7b43a754a7ffbb5beeec7eb
parentc0d3c9e0240e314b835c6585e26ad9b3bf21604d (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 Change-Id: Ide73d768b7cbb3a35be7160ce7555aeb2dca5235 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi> (cherry picked from commit 1f86957f1dd14cc538e7ad9ffee4eb63001af407)
-rw-r--r--src/corelib/kernel/qfunctions_winrt.h27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h
index 8cd7db778e..ef9c9187da 100644
--- a/src/corelib/kernel/qfunctions_winrt.h
+++ b/src/corelib/kernel/qfunctions_winrt.h
@@ -167,8 +167,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<IAsyncInfo> asyncInfo;
HRESULT hr = asyncOp.As(&asyncInfo);
@@ -183,6 +186,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 ERROR_TIMEOUT;
}
@@ -191,6 +196,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 ERROR_TIMEOUT;
}
@@ -221,20 +228,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;