diff options
| author | luigi1111 <luigi1111w@gmail.com> | 2019-06-25 14:02:40 -0500 |
|---|---|---|
| committer | luigi1111 <luigi1111w@gmail.com> | 2019-06-25 14:02:40 -0500 |
| commit | 036b3b56c543ea603c168c2e17405f8ca290ea40 (patch) | |
| tree | 39c1456c1faec86e1d745e39c8d1883f3de281e0 /src/qt/FutureScheduler.cpp | |
| parent | 3c3848633ee01c78a3dc7602912087cad25e49fc (diff) | |
| parent | be7810c5a877898d792cc7d4406dc05c3280b38f (diff) | |
| download | monzero-gui-036b3b56c543ea603c168c2e17405f8ca290ea40.tar.gz monzero-gui-036b3b56c543ea603c168c2e17405f8ca290ea40.tar.xz monzero-gui-036b3b56c543ea603c168c2e17405f8ca290ea40.zip | |
Merge pull request #2229
be7810c qt: implement FutureScheduler, always await async code to complete (xiphon)
Diffstat (limited to 'src/qt/FutureScheduler.cpp')
| -rw-r--r-- | src/qt/FutureScheduler.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/qt/FutureScheduler.cpp b/src/qt/FutureScheduler.cpp new file mode 100644 index 00000000..bdd47829 --- /dev/null +++ b/src/qt/FutureScheduler.cpp @@ -0,0 +1,89 @@ +#include "FutureScheduler.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<bool, QFuture<void>> FutureScheduler::run(std::function<void()> function) noexcept +{ + return execute<void>([this, function](QFutureWatcher<void> *) { + return QtConcurrent::run([this, function] { + try + { + function(); + } + catch (const std::exception &exception) + { + qWarning() << "Exception thrown from async function: " << exception.what(); + } + done(); + }); + }); +} + +QPair<bool, QFuture<QJSValueList>> FutureScheduler::run(std::function<QJSValueList() noexcept> function, const QJSValue &callback) noexcept +{ + if (!callback.isCallable()) + { + throw std::runtime_error("js callback must be callable"); + } + + return execute<QJSValueList>([this, function, callback](QFutureWatcher<QJSValueList> *watcher) { + connect(watcher, &QFutureWatcher<QJSValueList>::finished, [watcher, callback] { + QJSValue(callback).call(watcher->future().result()); + }); + return QtConcurrent::run([this, function] { + QJSValueList result; + try + { + result = function(); + } + catch (const std::exception &exception) + { + qWarning() << "Exception thrown from async function: " << exception.what(); + } + done(); + return result; + }); + }); +} + +bool FutureScheduler::add() noexcept +{ + QMutexLocker locker(&Mutex); + + if (Stopping) + { + return false; + } + + ++Alive; + return true; +} + +void FutureScheduler::done() noexcept +{ + { + QMutexLocker locker(&Mutex); + --Alive; + } + + Condition.wakeAll(); +} |
