If I understand the following code from the QFutureWatcher documentation correctly, then there is a race condition between the last to lines:
// Instantiate the objects and connect to the finished signal.
MyClass myObject;
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));
// Start the computation.
QFuture<int> future = QtConcurrent::run(...);
watcher.setFuture(future);
If the function ...
in the QtConcurrent::run(...)
finishes before the next line is called, then the watcher.finished()
signal will never be triggered. Is my assumption correct? How do I work around this bug?
I was running this snipped in a unit test and
QSignalSpy
was not getting the signals fromQFutureWatcher
. I solved the issue by calling explicitelyQCoreApplication::processEvents()
before the check:The signal is probably emitted from a thread, and in this situation, the signal is queued instead of being directly executed.
From http://doc.qt.io/qt-4.8/qfuturewatcher.html#setFuture
In other words, if
QtConcurrent::run(...)
completes beforesetFuture
is called,setFuture
will still emit a signal on the current state of theQFuture
. So, you don't need to do anything in order to avoid a race condition.However, depending on the rest of your code, you may need to call
QFuture::waitForFinished()
in order to ensure that yourMyClass
,QFuture
andQFutureWatcher
do not go out of scope beforeQtConcurrent::run(...)
completes.