title: How to cancel threads using QThreadPool
body: <p>I can't share code but theres a sort of example below.  Here's my problem. Imagine I have a controller class that has an instance of QThreadPool. This class keeps a list of worker objects. When I start a runnable, I create a worker and give it to the runnable. The runnable operates each worker on the different threads. When the runnable is done, it fires a signal back to the controller object. The controller object then reads the results from the worker and deletes the worker. The controller keeps a list of all workers so that it can set the cancel flag on the worker, so that the thread can exit early if necessary.  </p>
  
  <p>The problem is that the QThreadPool will wait for all threads to finish when it's destroyed, which will be in the controller destructor. Since signals are queued when fired from the threads, then potentially canceling the workers in the controller destructor will queue the signals to be delivered to the controller. But since the controller will be in the context of the destructor, those signals won't hit the controller slots, and therefore the worker objects won't get destroyed.</p>
  
  <p>Maybe I'm not dealing with the thread pool the way it should be. If I destroy the worker objects in the runnable, then there is potential for the worker to be destroyed before the another thread tries to cancel a worker. Can anyone recommend a good way of creating a cancelable thread pool?</p>
  
  <pre><code>class Controller : public QObject {
       Q_OBJECT
  public:
       virtual ~Controller();
       QThreadPool pool;
       void startTask();
       Q_SLOT void onWorkerDone(Worker * worker);
       QList&lt;Worker*&gt; workers;
       void cancelAll();
  }
  void Controller::startTask() {
       Worker * worker = new Worker();
       connect(pool, SIGNAL(done(Worker *)), this, SLOT(onWorkerDone(Worker *));
       workers &lt;&lt; worker;
       pool.start(new Runnable(worker);
  }
  void Controller::onWorkerDone(Worker * worker) {
      if ( worker ) {
          // read worker...
          delete worker;
      }
  }
  Controller::~Controller() {
       cancelAll();
       // Destructor now kills pool object.
       // The pool will wait until all threads complete.
       // If there are any workers still running on the
       // other threads, their done() signals will be 
       // queued to this instance, and since we're in 
       // the dtor, they won't make it to the slot, 
       // and worker won't get deleted.
  }
  void Controller::cancelAll() {
      // loop the list and call cancel.
  }
  </code></pre>