Other: Worker/Overseer/Threads improvements.

Added cancelled signal to worker and improved Overseer::wait.
Renamed Overseer::release() to Overseer::releaseWorker().
This commit is contained in:
Xavier Michelon
2022-08-20 10:22:35 +02:00
committed by Jakub
parent 090aaf8ee3
commit a520d636e8
3 changed files with 31 additions and 12 deletions

View File

@ -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;
}

View File

@ -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.

View File

@ -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.
};