// SPDX-License-Identifier: BSD-3-Clause // SPDX-FileCopyrightText: 2014-2022 The Monero Project #include "scheduler.h" FutureScheduler::FutureScheduler(QObject *parent) : QObject(parent), Alive(0), Stopping(false) { } FutureScheduler::~FutureScheduler() { shutdownWaitForFinished(); } void FutureScheduler::shutdownWaitForFinished() noexcept { QMutexLocker locker(&Mutex); Stopping = true; while (Alive > 0) { Condition.wait(&Mutex); } } QPair> FutureScheduler::run(std::function function) noexcept { return execute([this, function](QFutureWatcher *) { return QtConcurrent::run([this, function] { try { function(); } catch (const std::exception &exception) { qWarning() << "Exception thrown from async function: " << exception.what(); } done(); }); }); } QPair> FutureScheduler::run(const std::function &function, const std::function &callback) noexcept { return execute([this, function, callback](QFutureWatcher *watcher) { connect(watcher, &QFutureWatcher::finished, [watcher, callback] { callback(watcher->future().result()); }); return QtConcurrent::run([this, function] { QVariantMap result; try { result = function(); } catch (const std::exception &exception) { qWarning() << "Exception thrown from async function: " << exception.what(); } done(); return result; }); }); } bool FutureScheduler::stopping() const noexcept { return Stopping; } bool FutureScheduler::add() noexcept { QMutexLocker locker(&Mutex); if (Stopping) { return false; } ++Alive; return true; } void FutureScheduler::done() noexcept { { QMutexLocker locker(&Mutex); --Alive; } Condition.wakeAll(); }