That did the trick! I worked around the deletion order by moving the code that's in the destructor into a function called stopTask(). Then, I call this from the child's destructor so the run loop will get stopped BEFORE CentralTask() becomes a pure virtual function again. Worked like a charm.
Here's the updated code:
Seth
#ifndef INFINITETHREAD_H
#define INFINITETHREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
class InfiniteThread
: public QThread{
Q_OBJECT
public:
explicit InfiniteThread
(QObject *parent
= 0);
~InfiniteThread();
void startTask();
void stopTask();
signals:
void reportProgress
(int pProg,
QString message
);
void taskDone(bool pSuccess);
protected:
void run();
// Override this in the child class
virtual bool centralTask() = 0;
bool restart;
bool abort;
};
#endif // INFINITETHREAD_H
#ifndef INFINITETHREAD_H
#define INFINITETHREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
class InfiniteThread : public QThread
{
Q_OBJECT
public:
explicit InfiniteThread(QObject *parent = 0);
~InfiniteThread();
void startTask();
void stopTask();
signals:
void reportProgress(int pProg, QString message);
void taskDone(bool pSuccess);
protected:
void run();
// Override this in the child class
virtual bool centralTask() = 0;
QMutex mutex;
QWaitCondition condition;
bool restart;
bool abort;
};
#endif // INFINITETHREAD_H
To copy to clipboard, switch view to plain text mode
#include "infinitethread.h"
InfiniteThread
::InfiniteThread(QObject *parent
) :{
restart = false;
abort = false;
}
InfiniteThread::~InfiniteThread()
{
}
void InfiniteThread::stopTask()
{
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();
wait();
}
void InfiniteThread::startTask()
{
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}
}
void InfiniteThread::run()
{
forever {
// Perform central task
bool result = centralTask();
if(!restart) emit taskDone(result);
// Abort thread if requested
if(abort) return;
// Restart when new central task is given
mutex.lock();
if(!restart) condition.wait(&mutex);
restart = false;
mutex.unlock();
}
}
#include "infinitethread.h"
InfiniteThread::InfiniteThread(QObject *parent) :
QThread(parent)
{
restart = false;
abort = false;
}
InfiniteThread::~InfiniteThread()
{
}
void InfiniteThread::stopTask()
{
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();
wait();
}
void InfiniteThread::startTask()
{
QMutexLocker locker(&mutex);
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}
}
void InfiniteThread::run()
{
forever {
// Perform central task
bool result = centralTask();
if(!restart) emit taskDone(result);
// Abort thread if requested
if(abort) return;
// Restart when new central task is given
mutex.lock();
if(!restart) condition.wait(&mutex);
restart = false;
mutex.unlock();
}
}
To copy to clipboard, switch view to plain text mode
Bookmarks