Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosmtblockingcallsgateway_p.h
Go to the documentation of this file.
1// Copyright (C) 2025 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 QOHOSMTBLOCKINGCALLSGATEWAY_H
5#define QOHOSMTBLOCKINGCALLSGATEWAY_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/qohoscommon_p.h>
19#include <QtCore/qglobal.h>
20#include <chrono>
21#include <condition_variable>
22#include <functional>
23#include <future>
24#include <memory>
25#include <mutex>
26#include <qohosplugincore.h>
27#include <utility>
28
29QT_BEGIN_NAMESPACE
30
31namespace QtOhos {
32
33template<typename SlaveContext>
34class QOhosMtBlockingCallsGateway : public std::enable_shared_from_this<QOhosMtBlockingCallsGateway<SlaveContext>>
35{
36public:
44
45 static std::shared_ptr<QOhosMtBlockingCallsGateway<SlaveContext>> makeInstance(
46 QOhosConsumer<std::function<void()>> masterThreadTasksExecutor,
47 QOhosConsumer<std::function<void(SlaveContext &)>> slaveThreadTasksExecutor);
48
49 void invokeInMasterThread(std::function<void()> &&task);
50 void invokeInSlaveThread(std::function<void(SlaveContext &)> &&task);
51
53 std::function<void(SlaveContext &, QOhosTaskPromise<>)> &&task,
54 const std::string &callerContextName = std::string());
56 QOhosConsumer<std::function<void()>> &&task,
58
59private:
60 struct MasterThreadTaskState
61 {
62 bool started = false;
63 QOhosOptional<MasterThreadTaskResult> result;
64 std::condition_variable resultSetCondVar;
65 };
66
68 QOhosConsumer<std::function<void()>> masterThreadTasksExecutor,
69 QOhosConsumer<std::function<void(SlaveContext &)>> slaveThreadTasksExecutor);
70
71 QOhosConsumer<std::function<void()>> m_masterThreadTasksExecutor;
72 QOhosConsumer<std::function<void(SlaveContext &)>> m_slaveThreadTasksExecutor;
73 std::mutex m_waitStateMutex;
74 bool m_masterWaiting = false;
75 std::shared_ptr<MasterThreadTaskState> m_masterThreadTaskState;
76};
77
78template<typename SlaveContext>
87
88template<typename SlaveContext>
89QOhosMtBlockingCallsGateway<SlaveContext>::QOhosMtBlockingCallsGateway(
90 QOhosConsumer<std::function<void()>> masterThreadTasksExecutor,
91 QOhosConsumer<std::function<void(SlaveContext &)>> slaveThreadTasksExecutor)
92 : m_masterThreadTasksExecutor(std::move(masterThreadTasksExecutor))
93 , m_slaveThreadTasksExecutor(std::move(slaveThreadTasksExecutor))
94{
95}
96
97template<typename SlaveContext>
98void QOhosMtBlockingCallsGateway<SlaveContext>::invokeInMasterThread(std::function<void()> &&task)
99{
100 m_masterThreadTasksExecutor(std::move(task));
101}
102
103template<typename SlaveContext>
104void QOhosMtBlockingCallsGateway<SlaveContext>::invokeInSlaveThread(std::function<void(SlaveContext &)> &&task)
105{
106 m_slaveThreadTasksExecutor(std::move(task));
107}
108
109template<typename SlaveContext>
111 std::function<void(SlaveContext &, QOhosTaskPromise<>)> &&task,
112 const std::string &callerContextName)
113{
114 const auto funcInfo = Q_FUNC_INFO;
115
116 {
117 std::lock_guard<std::mutex> waitStateLock(m_waitStateMutex);
118 if (m_masterThreadTaskState) {
119 auto taskState = std::exchange(m_masterThreadTaskState, nullptr);
120 taskState->result = MasterThreadTaskResult::CancelledByDeadlock;
121 taskState->resultSetCondVar.notify_all();
122 }
123 m_masterWaiting = true;
124 }
125
126 auto taskFinishedPromise = std::make_shared<std::promise<void>>();
127 auto taskFinishedFuture = taskFinishedPromise->get_future();
128
129 auto sharedTaskPromise = std::make_shared<QOhosTaskPromise<>>(
130 [taskFinishedPromise]() {
131 taskFinishedPromise->set_value();
132 },
133 [funcInfo, callerContextName]() {
134 qOhosReportFatalErrorAndAbort(
135 "%s: promise destroyed without notifying the caller: %s",
136 funcInfo, callerContextName.c_str());
137 },
138 callerContextName);
139
141 [task = std::move(task), sharedTaskPromise](SlaveContext &context) {
142 task(context, std::move(*sharedTaskPromise));
143 });
144 taskFinishedFuture.wait();
145
146 {
147 std::lock_guard<std::mutex> waitStateLock(m_waitStateMutex);
148 m_masterWaiting = false;
149 }
150}
151
152template<typename SlaveContext>
154QOhosMtBlockingCallsGateway<SlaveContext>::tryInvokeInMasterThreadAndTryWaitForContinue(
155 QOhosConsumer<std::function<void()>> &&task,
157{
159
160 {
162 if (m_masterWaiting)
165 }
166
168
169 auto continueFunc = [weakSelf, taskState]() {
170 auto self = weakSelf.lock();
171 if (self) {
177 }
178 }
179 };
180
183 auto self = weakSelf.lock();
184 if (self) {
185 bool upToDate;
186 {
191 }
192 if (upToDate)
194 }
195 });
196
198 {
202 [&]() {
203 return taskState->result.has_value();
204 });
209 }
210
211 return result;
212}
213
214}
215
216QT_END_NAMESPACE
217
218#endif
JsState & jsState() const
~JsState() override
void invokeInSlaveThread(std::function< void(SlaveContext &)> &&task)
void runInSlaveThreadAndWaitForContinue(std::function< void(SlaveContext &, QOhosTaskPromise<>)> &&task, const std::string &callerContextName=std::string())
static std::shared_ptr< QOhosMtBlockingCallsGateway< SlaveContext > > makeInstance(QOhosConsumer< std::function< void()> > masterThreadTasksExecutor, QOhosConsumer< std::function< void(SlaveContext &)> > slaveThreadTasksExecutor)
void invokeInMasterThread(std::function< void()> &&task)
void * tryCastWithTypeIdObject(const void *matchTypeIdObject) final
static std::shared_ptr< QUiAbilityPeer > tryCastFromQAbilityPeerOrNull(std::shared_ptr< QAbilityPeer > qAbilityPeer)
~QUiAbilityPeer() override
void invokeInJsThread(std::function< void(JsState &)> task)
void dispatchNewWant(QNapi::Object want, QNapi::Object launchParam)
void removeMatchingJsQAbilityPeer(QNapi::Object qAbility)
void runInJsThreadAndWait(const std::function< void(JsState &)> &task, std::string callerContextName={})
void initJsThreadState(napi_env env, std::map< std::string, QNapi::Reference< QNapi::Function > > &&jsModulesFactories, std::shared_ptr< AppFunctions > appFunctions, QtRunMode qtRunMode)
Q_REQUIRED_RESULT bool tryInvokeInQtThreadAndTryWaitForContinue(std::function< void(std::function< void()>)> &&task, std::chrono::nanoseconds timeout)
void invokeInJsThreadAndWaitForContinue(std::function< void(JsState &, QOhosTaskPromise<>)> &&task, std::string callerContextName={})
void addJsQAbilityPeer(std::shared_ptr< QAbilityPeer > qAbilityPeer)