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

Qt Code:
  1. #ifndef INFINITETHREAD_H
  2. #define INFINITETHREAD_H
  3.  
  4. #include <QThread>
  5. #include <QMutex>
  6. #include <QWaitCondition>
  7.  
  8. class InfiniteThread : public QThread
  9. {
  10. Q_OBJECT
  11.  
  12. public:
  13. explicit InfiniteThread(QObject *parent = 0);
  14. ~InfiniteThread();
  15.  
  16. void startTask();
  17. void stopTask();
  18.  
  19. signals:
  20. void reportProgress(int pProg, QString message);
  21. void taskDone(bool pSuccess);
  22.  
  23. protected:
  24. void run();
  25.  
  26. // Override this in the child class
  27. virtual bool centralTask() = 0;
  28.  
  29. QMutex mutex;
  30. QWaitCondition condition;
  31. bool restart;
  32. bool abort;
  33. };
  34.  
  35. #endif // INFINITETHREAD_H
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. #include "infinitethread.h"
  2.  
  3. InfiniteThread::InfiniteThread(QObject *parent) :
  4. QThread(parent)
  5. {
  6. restart = false;
  7. abort = false;
  8. }
  9.  
  10. InfiniteThread::~InfiniteThread()
  11. {
  12. }
  13.  
  14. void InfiniteThread::stopTask()
  15. {
  16. mutex.lock();
  17. abort = true;
  18. condition.wakeOne();
  19. mutex.unlock();
  20.  
  21. wait();
  22. }
  23.  
  24. void InfiniteThread::startTask()
  25. {
  26. QMutexLocker locker(&mutex);
  27.  
  28. if (!isRunning()) {
  29. start(LowPriority);
  30. } else {
  31. restart = true;
  32. condition.wakeOne();
  33. }
  34. }
  35.  
  36. void InfiniteThread::run()
  37. {
  38. forever {
  39. // Perform central task
  40. bool result = centralTask();
  41. if(!restart) emit taskDone(result);
  42.  
  43. // Abort thread if requested
  44. if(abort) return;
  45.  
  46. // Restart when new central task is given
  47. mutex.lock();
  48. if(!restart) condition.wait(&mutex);
  49. restart = false;
  50. mutex.unlock();
  51. }
  52. }
To copy to clipboard, switch view to plain text mode