Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfunctions_winrt_p.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QFUNCTIONS_WINRT_P_H
5#define QFUNCTIONS_WINRT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qglobal_p.h>
19
20#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
21
22#include <QtCore/QCoreApplication>
23#include <QtCore/QThread>
24#include <QtCore/QAbstractEventDispatcher>
25#include <QtCore/QElapsedTimer>
26#include <QtCore/qt_windows.h>
27
28#include <wrl.h>
29#include <windows.foundation.h>
30
31// Convenience macros for handling HRESULT values
32#define RETURN_IF_FAILED(msg, ret) \
33 if (FAILED(hr)) { \
34 qErrnoWarning(hr, msg); \
35 ret; \
36 }
37
38#define RETURN_IF_FAILED_WITH_ARGS(msg, ret, ...) \
39 if (FAILED(hr)) { \
40 qErrnoWarning(hr, msg, __VA_ARGS__); \
41 ret; \
42 }
43
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__)
52
53#define Q_ASSERT_SUCCEEDED(hr) \
54 Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
55
57
58namespace QWinRTFunctions {
59
60// Synchronization methods
61enum AwaitStyle
62{
63 YieldThread = 0,
64 ProcessThreadEvents = 1,
65 ProcessMainThreadEvents = 2
66};
67
68using EarlyExitConditionFunction = std::function<bool(void)>;
69
70template<typename T>
71static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr<T> &asyncOp, AwaitStyle awaitStyle,
72 uint timeout, EarlyExitConditionFunction func)
73{
75 HRESULT hr = asyncOp.As(&asyncInfo);
76 if (FAILED(hr))
77 return hr;
78
79 AsyncStatus status;
81 if (timeout)
82 t.start();
83 switch (awaitStyle) {
84 case ProcessMainThreadEvents:
85 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
87 if (func && func())
88 return E_ABORT;
89 if (timeout && t.hasExpired(timeout))
90 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
91 }
92 break;
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);
97 if (func && func())
98 return E_ABORT;
99 if (timeout && t.hasExpired(timeout))
100 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
101 }
102 break;
103 }
104 // fall through
105 default:
106 case YieldThread:
107 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
109 if (timeout && t.hasExpired(timeout))
110 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
111 }
112 break;
113 }
114
115 if (FAILED(hr) || status != AsyncStatus::Completed) {
116 HRESULT ec;
117 hr = asyncInfo->get_ErrorCode(&ec);
118 if (FAILED(hr))
119 return hr;
120 hr = asyncInfo->Close();
121 if (FAILED(hr))
122 return hr;
123 return ec;
124 }
125
126 return hr;
127}
128
129template<typename T>
130static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp,
131 AwaitStyle awaitStyle = YieldThread, uint timeout = 0,
132 EarlyExitConditionFunction func = nullptr)
133{
134 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
135 if (FAILED(hr))
136 return hr;
137
138 return asyncOp->GetResults();
139}
140
141template<typename T, typename U>
142static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results,
143 AwaitStyle awaitStyle = YieldThread, uint timeout = 0,
144 EarlyExitConditionFunction func = nullptr)
145{
146 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
147 if (FAILED(hr))
148 return hr;
149
150 return asyncOp->GetResults(results);
151}
152
153} // QWinRTFunctions
154
156
157#endif // Q_OS_WIN && Q_CC_MSVC
158
159#endif // QFUNCTIONS_WINRT_P_H
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Processes some pending events for the calling thread according to the specified flags.
\inmodule QtCore
void start() noexcept
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
static QThread * currentThread()
Definition qthread.cpp:1039
static void yieldCurrentThread()
Definition qthread.cpp:1054
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE bool await(IAsyncOperation< T > &&asyncInfo, T &result, uint timeout=0)
GLbitfield GLuint64 timeout
[4]
GLenum func
Definition qopenglext.h:663
GLdouble GLdouble t
Definition qopenglext.h:243
unsigned int uint
Definition qtypes.h:34
long HRESULT