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>bb10
parent
0acada9c7b
commit
1f86957f1d
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue