Revision control

Copy as Markdown

// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QOHOSBATCHINGREQUESTSHANDLER_H
#define QOHOSBATCHINGREQUESTSHANDLER_H
#include <QtCore/qglobal.h>
#include <QtCore/private/qcore_ohos_p.h>
#include <QtCore/private/qohoscommon_p.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qobject.h>
#include <functional>
#include <memory>
#include <mutex>
#include <vector>
QT_BEGIN_NAMESPACE
namespace details_qohosbatchingrequestshandler_h {
inline QOhosConsumer<std::function<void()>> makeQtThreadTasksExecutor(QtOhos::QObjectThreadSafeRef qtContext)
{
return [qtContext](std::function<void()> task) {
qtContext.visitInQtThreadIfAlive(
[task = std::move(task)](auto &) {
task();
});
};
}
template<typename Batch>
class QtOhosBatchingAsyncMTRequestsHandler : public std::enable_shared_from_this<QtOhosBatchingAsyncMTRequestsHandler<Batch>>
{
public:
QtOhosBatchingAsyncMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor, std::function<void(Batch &&)> targetThreadHandleBatchFunc);
void updateBatch(const std::function<void(Batch &)> &updateFunc);
private:
void postRequestTaskIfNeeded();
std::mutex m_batchMutex;
Batch m_batch = {};
bool m_batchPending = false;
QOhosConsumer<std::function<void()>> m_tasksExecutor;
std::function<void(Batch &&)> m_targetThreadHandleBatchFunc;
};
template<typename Batch>
QtOhosBatchingAsyncMTRequestsHandler<Batch>::QtOhosBatchingAsyncMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor, std::function<void(Batch &&)> targetThreadHandleBatchFunc)
: m_tasksExecutor(tasksExecutor)
, m_targetThreadHandleBatchFunc(std::move(targetThreadHandleBatchFunc))
{
}
template<typename Batch>
void QtOhosBatchingAsyncMTRequestsHandler<Batch>::updateBatch(const std::function<void(Batch &)> &updateFunc)
{
std::lock_guard<std::mutex> requestLock(m_batchMutex);
updateFunc(m_batch);
if (!m_batchPending) {
auto weakSelf = std::weak_ptr<QtOhosBatchingAsyncMTRequestsHandler<Batch>>(this->shared_from_this());
m_tasksExecutor(
[weakSelf]() {
auto self = weakSelf.lock();
if (self) {
std::unique_ptr<Batch> optRequest;
{
std::lock_guard<std::mutex> requestLock(self->m_batchMutex);
if (self->m_batchPending) {
optRequest = std::make_unique<Batch>(std::exchange(self->m_batch, Batch()));
self->m_batchPending = false;
}
}
if (optRequest)
self->m_targetThreadHandleBatchFunc(std::move(*optRequest));
}
});
m_batchPending = true;
}
}
}
template<typename Request>
std::function<void(std::function<void(Request &)>)> makeQtOhosBatchingMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor,
QOhosConsumer<Request &&> targetThreadBatchConsumer);
template<typename QtRequest>
std::function<void(std::function<void(QtRequest &)>)> makeQtOhosBatchingQtRequestsHandler(
QtOhos::QObjectThreadSafeRef qtContext, std::function<void(QtRequest &&)> qtHandleRequestFunc);
template<typename QtRequest>
QOhosConsumer<QtRequest> makeQtOhosSimpleBatchingQtRequestsHandler(
QtOhos::QObjectThreadSafeRef qtContext, QOhosConsumer<std::vector<QtRequest>> qtThreadBatchConsumer);
template<typename Request>
QOhosConsumer<Request> makeQtOhosSimpleBatchingMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor,
QOhosConsumer<std::vector<Request>> targetThreadBatchConsumer);
template<typename Request>
std::function<void(std::function<void(Request &)>)> makeQtOhosBatchingMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor,
QOhosConsumer<Request &&> targetThreadBatchConsumer)
{
using namespace details_qohosbatchingrequestshandler_h;
auto requestsHandler = std::make_shared<QtOhosBatchingAsyncMTRequestsHandler<Request>>(
std::move(tasksExecutor), std::move(targetThreadBatchConsumer));
return [requestsHandler](const std::function<void(Request &)> &updateFunc) {
requestsHandler->updateBatch(updateFunc);
};
}
template<typename QtRequest>
std::function<void(std::function<void(QtRequest &)>)> makeQtOhosBatchingQtRequestsHandler(
QtOhos::QObjectThreadSafeRef qtContext, std::function<void(QtRequest &&)> qtHandleRequestFunc)
{
using namespace details_qohosbatchingrequestshandler_h;
return makeQtOhosBatchingMTRequestsHandler(
makeQtThreadTasksExecutor(qtContext), std::move(qtHandleRequestFunc));
}
template<typename QtRequest>
QOhosConsumer<QtRequest> makeQtOhosSimpleBatchingQtRequestsHandler(
QtOhos::QObjectThreadSafeRef qtContext, QOhosConsumer<std::vector<QtRequest>> qtThreadBatchConsumer)
{
using namespace details_qohosbatchingrequestshandler_h;
return makeQtOhosSimpleBatchingMTRequestsHandler(
makeQtThreadTasksExecutor(qtContext), std::move(qtThreadBatchConsumer));
}
template<typename Request>
QOhosConsumer<Request> makeQtOhosSimpleBatchingMTRequestsHandler(
QOhosConsumer<std::function<void()>> tasksExecutor,
QOhosConsumer<std::vector<Request>> targetThreadBatchConsumer)
{
using namespace details_qohosbatchingrequestshandler_h;
auto baseRequestsHandler = std::make_shared<QtOhosBatchingAsyncMTRequestsHandler<std::vector<Request>>>(
std::move(tasksExecutor), std::move(targetThreadBatchConsumer));
return [baseRequestsHandler = std::move(baseRequestsHandler)](Request request) {
baseRequestsHandler->updateBatch(
[&](std::vector<Request> &batch) {
batch.push_back(std::move(request));
});
};
}
QT_END_NAMESPACE
#endif