From a520d636e833c62e5ea8fbba8d8a94f1f57af6ef Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Sat, 20 Aug 2022 10:22:35 +0200 Subject: [PATCH] Other: Worker/Overseer/Threads improvements. Added cancelled signal to worker and improved Overseer::wait. Renamed Overseer::release() to Overseer::releaseWorker(). --- .../bridgepp/bridgepp/Worker/Overseer.cpp | 40 ++++++++++++++----- .../bridgepp/bridgepp/Worker/Overseer.h | 2 +- .../bridgepp/bridgepp/Worker/Worker.h | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.cpp index 6e176669..241d0f85 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.cpp @@ -43,7 +43,7 @@ Overseer::Overseer(Worker *worker, QObject *parent) //**************************************************************************************************************************************************** Overseer::~Overseer() { - this->release(); + this->releaseWorker(); } @@ -61,11 +61,13 @@ void Overseer::startWorker(bool autorelease) const connect(thread_, &QThread::started, worker_, &Worker::run); connect(worker_, &Worker::finished, [&]() {thread_->quit(); }); // Safety, normally the thread already properly quits. connect(worker_, &Worker::error, [&]() { thread_->quit(); }); + connect(worker_, &Worker::cancelled, [&]() { thread_->quit(); }); if (autorelease) { - connect(worker_, &Worker::error, this, &Overseer::release); - connect(worker_, &Worker::finished, this, &Overseer::release); + connect(worker_, &Worker::error, this, &Overseer::releaseWorker); + connect(worker_, &Worker::cancelled, this, &Overseer::releaseWorker); + connect(worker_, &Worker::finished, this, &Overseer::releaseWorker); } thread_->start(); @@ -75,7 +77,7 @@ void Overseer::startWorker(bool autorelease) const //**************************************************************************************************************************************************** // //**************************************************************************************************************************************************** -void Overseer::release() +void Overseer::releaseWorker() { if (worker_) { @@ -115,16 +117,32 @@ bool Overseer::isFinished() const //**************************************************************************************************************************************************** bool Overseer::wait(qint32 timeoutMs) const { - QElapsedTimer timer; - timer.start(); + if (this->isFinished()) + return true; - while (!this->isFinished()) { - if ((timeoutMs >= 0) && (timer.elapsed() > timeoutMs)) - return false; - QThread::msleep(10); + QEventLoop loop; + QTimer timer; + bool inTime = true; + if (timeoutMs >= 0) + { + connect(&timer, &QTimer::timeout, &loop, [&]() { loop.quit(); inTime = false; } ); + timer.setSingleShot(true); + timer.start(timeoutMs); } - return true; + QTimer repeatTimer; // safety timer, used if for some reason the worker does not emit finished(), error() or cancelled() + repeatTimer.setSingleShot(false); + repeatTimer.setInterval(100); + connect(&repeatTimer, &QTimer::timeout, [&]() { if (this->isFinished()) { loop.quit(); }}); + repeatTimer.start(); + + connect(worker_, &Worker::finished, &loop, &QEventLoop::quit); + connect(worker_, &Worker::error, &loop, &QEventLoop::quit); + connect(worker_, &Worker::cancelled, &loop, &QEventLoop::quit); + + loop.exec(); + + return inTime; } diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.h index cafa3820..57952d5d 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Overseer.h @@ -46,7 +46,7 @@ public: // member functions. public slots: void startWorker(bool autorelease) const; ///< Run the worker. - void release(); ///< Delete the worker and its thread. + void releaseWorker(); ///< Delete the worker and its thread. public: // data members. QThread *thread_{nullptr}; ///< The thread. diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Worker.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Worker.h index d893e8bc..8f407953 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Worker.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Worker/Worker.h @@ -47,6 +47,7 @@ signals: void started(); ///< Signal for the start of the worker void finished(); ///< Signal for the end of the worker void error(QString const &message); ///< Signal for errors. After an error, worker ends and finished is NOT emitted. + void cancelled(); ///< Signal for the cancellation of the worker. };