So I have the following situation:
I have a QThread that runs an eventloop (i.e. no custom run function). To stop the thread, I send a signal to a worker in that thread. This worker then does cleanups etc and at some point is done and quits the thread.
The problem I am facing right now is: If I invoke the workers stop method and then immediatly wait for the thread to finish it will never do so because the workers done signal does not get processed. Code:
class Worker {
signals:
void done();
public slots:
void stop() {
//dummy code to illustrate what happens here:
QTimer::singleShot(3000, this, &Worker::done);
}
};
// in the main thread
auto thread = new QThread();
auto worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::done, thread, &QThread::quit); //implicitly a queued connection
// ...
QMetaObject::invokeMethod(worker, "stop", Qt::QueuedConnection);
thread->wait(); //blocks here forever, because the connect is queued
Now reason the problem is obvious - Because I block on the main thread the slot can never be invoked (because queued connection) and thus quit is never called. However, if I simply call QThread::quit (or QThread::exit) directly from the worker (or use a DirectConnection) then there is no problem anymore because the eventloop of the main thread is no longer required to process the event.
So the actual question here is: Is that allowed? Can I call QThread::quit from within the actual thread? Or can this create Race conditions, deadlocks and other problems like that. The documentation does not mark the method as threadsafe - but the thread that is managed by QThread might be an exception.