I have a stream of real time data from some HW handled by a producer object.
This gets connected to a consumer that process it in it’s own thread to keep the gui responsive.
mainwindow::startProcessing(){
QObject::connect(producer,SIGNAL(dataReady(data*),consumer,SLOT(doData(data*)));
consumer->moveToThread(&consumerThread);
consumerThread.start();
}
mainwindow::stopProcessing(){
producer->disconnect(SIGNAL(dataReady(data*));
consumer->cleanup();
delete consumer;
}
consumer::doData(data* x) {
mutex.lock();
processingObject stuff
mutex.unlock()
}
consumer::cleanup() {
mutex.tryLock();
.... blah ....
delete processingObject; // then doData gets called again
}
My problem is that after I destroy the consumer object – I still get signals posted to it, even after doing a disconnect. I’ve tried an increasingly complex set of mutexes to try and stop this but the ideal solution would be for the cleanup to wait until all outstanding signals are processed.
Is there anyway to monitor how many unhandled signals are queued for a slot? Or anyway to clear them?
You seem to be destroying the consumer object from a different thread than the one that it lives in. QObject would normally handle all disconnection and event queue clearing itself upon destruction, were it to be done in the correct thread. From Qt’s documentation:
Just put the cleanup in the destructor of the consumer, and use
QMetaObject::invokeMethod(consumer, "deleteLater");to get the consumer to destroy itself from inside its own thread. Using invokeMethod on the slot will send the call to deleteLater in thread-safe manner, which seems to be necessary as I see no documentation that says deleteLater is thread-safe itself. If you must block until the consumer is destroyed, you can specify the connection type to beQt::BlockingQueuedConnection, but otherwise the default ofQt::AutoConnectionshould be fine.