Greetings!

I'm having a problem with my QThread classes. I based them on the Qt Example Mandlebrot (I'm also doing an long rendering process). I extracted the core mutex and waitCondition syncronization that was in the renderThread into it's own class (which I call InfiniteThread) and then I sub-class this to specialize what task that thread will perform.

Problem is, whenever an instance of InfiniteThread is destroyed and the destructor gets called I get a SIGABRT and the following console output:

pure virtual method called
terminate called without an active exception
The program has unexpectedly finished.
Here's the top of the stack at the time:

Qt Code:
  1. 0 __semwait_signal 0 0x00007fff87ecdeb6
  2. 1 _pthread_cond_wait 0 0x00007fff87ed1cd1
  3. 2 QWaitCondition::wait 0 0x000000010103bfa0
  4. 3 QThread::wait 0 0x00000001010a419e
  5. 4 InfiniteThread::~InfiniteThread infinitethread.cpp 17 0x000000010001022c
  6. 5 EMSampleThread::~EMSampleThread emsamplethread.cpp 18 0x000000010000fbfd
  7. 6 RFViewer::~RFViewer rfviewer.cpp 50 0x0000000100008a8f
  8. 7 main main.cpp 10 0x000000010000602a
To copy to clipboard, switch view to plain text mode 

So the SIGABRT seems to be coming from QThread::wait(), which is called in ~InfiniteThread(). Code for InfiniteThread is included below. Note that InfiniteThread::centralTask() is a pure-virtual member that is re-implemented to specialize the thread for a specific task.

Like I mentioned before, InfiniteThread is based entirely on renderthread.cpp in the Mandlebrot example and it does not have this problem. Any help is much appreciated. I'm new to threading but I am pretty comfortable with Qt.

Thanks!
Seth

InfiniteThread.h:
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. signals:
  17. void reportProgress(int pProg, QString message);
  18. void taskDone(bool pSuccess);
  19.  
  20. protected:
  21. void startTask();
  22. void run();
  23.  
  24. // Override this in the child class
  25. virtual bool centralTask() = 0;
  26.  
  27. QMutex mutex;
  28. QWaitCondition condition;
  29. bool restart;
  30. bool abort;
  31. };
  32.  
  33. #endif // INFINITETHREAD_H
To copy to clipboard, switch view to plain text mode 

InfiniteThread.cpp:
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. mutex.lock();
  13. abort = true;
  14. condition.wakeOne();
  15. mutex.unlock();
  16.  
  17. wait();
  18. }
  19.  
  20. void InfiniteThread::startTask()
  21. {
  22. QMutexLocker locker(&mutex);
  23.  
  24. if (!isRunning()) {
  25. start(LowPriority);
  26. } else {
  27. restart = true;
  28. condition.wakeOne();
  29. }
  30. }
  31.  
  32. void InfiniteThread::run()
  33. {
  34. forever {
  35. // Perform central task
  36. bool result = centralTask();
  37. if(!restart) emit taskDone(result);
  38.  
  39. // Abort thread if requested
  40. if(abort) return;
  41.  
  42. // Restart when new central task is given
  43. mutex.lock();
  44. if(!restart) condition.wait(&mutex);
  45. restart = false;
  46. mutex.unlock();
  47. }
  48. }
To copy to clipboard, switch view to plain text mode