PDA

View Full Version : Cross-thread signal emission - does it wait for the slots?



psih128
19th January 2010, 20:37
Suppose I have a background thread that at some point emits a signal from an object (the object belongs to the GUI thread!):


qDebug() << "before signal emitted";
emit mySignal();
qDebug() << "after signal emitted";

This signal is connected to a slot on another object from the GUI thread:


void QMyObject::mySlot() {
qDebug() << "signal received";
}

In the debug output I see the following order of messages:


before signal emitted
after signal emitted
signal received

Which makes me think that when the signal is emitted, it does not wait for the slots. Although the documentation states the opposite:

Execution of the code following the emit statement will occur once all slots have returned

Basically in my case I would want the emitting side to wait for all the slots to process the signal. The behavior I observe is probably due to cross-thread execution, but it should be uniform for all cases, shouldn't it?

Thanks
Anton

squidge
19th January 2010, 20:50
If you use DirectConnection, then the documentation is correct. If you use QueuedConnection, then the signal is posted to the event queue and processed when the event queue is next run.

Signals between threads MUST be queued, as you can't do inter-thread calls.

The appropriate connection type is automatically chosen for you based on whether the sender and receiver are in the same thread.

wysota
19th January 2010, 21:08
Which makes me think that when the signal is emitted, it does not wait for the slots. Although the documentation states the opposite:


Execution of the code following the emit statement will occur once all slots have returned


Did you read the next sentence of the reference?


The situation is slightly different when using queued connections; in such a case, the code following the emit keyword will continue immediately, and the slots will be executed later.

If you want to block the signalling thread until all receivers return, use the Qt::BlockingQueuedConnection connection type.

psih128
19th January 2010, 21:26
Oh thanks guys! I should pay more attention..

Did you read the next sentence of the reference?
Actually no.. I was so happy to find the "reason" of my problem, than I immediately proceeded to QtCentre xD