4#ifndef QFUNCTIONS_WINRT_P_H
5#define QFUNCTIONS_WINRT_P_H
18#include <QtCore/private/qglobal_p.h>
20#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
22#include <QtCore/QCoreApplication>
23#include <QtCore/QThread>
24#include <QtCore/QAbstractEventDispatcher>
25#include <QtCore/QElapsedTimer>
26#include <QtCore/qt_windows.h>
27#include <QtCore/private/qcomptr_p.h>
29#include <windows.foundation.h>
32#define RETURN_IF_FAILED(msg, ret)
34 qErrnoWarning(hr, msg);
38#define RETURN_IF_FAILED_WITH_ARGS(msg, ret, ...)
40 qErrnoWarning(hr, msg, __VA_ARGS__);
44#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr)
45#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK)
46#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false)
47#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return)
48#define RETURN_HR_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return hr, __VA_ARGS__)
49#define RETURN_OK_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return S_OK, __VA_ARGS__)
50#define RETURN_FALSE_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return false, __VA_ARGS__)
51#define RETURN_VOID_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return, __VA_ARGS__)
53#define Q_ASSERT_SUCCEEDED(hr)
54 Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
58namespace QWinRTFunctions {
64 ProcessThreadEvents = 1,
65 ProcessMainThreadEvents = 2
68using EarlyExitConditionFunction = std::function<
bool(
void)>;
71static inline HRESULT _await_impl(
const ComPtr<T> &asyncOp, AwaitStyle awaitStyle, uint timeout,
72 EarlyExitConditionFunction func)
74 ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
75 HRESULT hr = asyncOp.As(&asyncInfo);
84 case ProcessMainThreadEvents:
85 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
86 QCoreApplication::processEvents();
89 if (timeout && t.hasExpired(timeout))
90 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
93 case ProcessThreadEvents:
94 if (QAbstractEventDispatcher *dispatcher = QThread::currentThread()->eventDispatcher()) {
95 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
96 dispatcher->processEvents(QEventLoop::AllEvents);
99 if (timeout && t.hasExpired(timeout))
100 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
107 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
108 QThread::yieldCurrentThread();
109 if (timeout && t.hasExpired(timeout))
110 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
115 if (FAILED(hr) || status != AsyncStatus::Completed) {
117 hr = asyncInfo->get_ErrorCode(&ec);
120 hr = asyncInfo->Close();
130static inline HRESULT await(
const ComPtr<T> &asyncOp, AwaitStyle awaitStyle = YieldThread,
131 uint timeout = 0, EarlyExitConditionFunction func =
nullptr)
133 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
137 return asyncOp->GetResults();
140template<
typename T,
typename U>
141static inline HRESULT await(
const ComPtr<T> &asyncOp, U *results,
142 AwaitStyle awaitStyle = YieldThread, uint timeout = 0,
143 EarlyExitConditionFunction func =
nullptr)
145 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
149 return asyncOp->GetResults(results);