Do Qt::QueuedConnection signals always invoke in order? - c++

Related to Qt: Do events get processed in order?
Do Qt::QueuedConnection signals always get invoked in order?
So:
void A::func()
{
emit first_signal();
emit second_signal();
}
If these are both connected by Qt::QueuedConnection to slots will they always be invoked in the order first_signal() then second_signal()?

Given the fact that bug(s) regarding the event prioritization are still being fixed very recently (target version 4.8.0), better don't rely on it. The observation that docs avoid any bold statements most probably means that the devs are simply not so sure.

If the documentation does not state it, you should rather not assume it.

Related

Replacement for exceptions if QObject is used with Signal and Slots

I tried to break down my problem to a small example. The real problem is a more complex communication:
I have a function that triggers a communication and connects and sends messages to a server. If there is an answer, the Client-class emits a signal containing the answer.
void communicate()
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
void reactToAnswer(QString answer)
{
parser.parseAnswer() // an error could occur
}
What if an error is detected in the slot in which the response is processed? I would like to stop the execution of the function communicate(). This means that the function client.sendMessage("HelloWorld") should no longer be executed.
In my naivety I tried to handle the problem with exceptions:
void communicate()
{
try
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
catch(myException)
{
// do something
}
void reactToAnswer(QString answer)
{
if( !parser.parseAnswer() )
{
throw myException;
}
}
This does not work, throwing an exception from a slot invoked by a qt-signal is undefined behaviour. The usual way is to reimplement QApplication::notify() resp. QCoreApplication()::notify, but this does not work for me. There is already a QApplication for the GUI and I want the communication class (QObject) to stand alone. All things should be treated within this class.
I hope I explained the problem comprehensibly. I do not want to use exceptions in any case, other ways to stop the communication are also right for me.
Thanks in advance!
I'm not sure that what you are trying to accomplish is a particularly good fit for the signals-and-slots paradigm... perhaps you want to go with just a regular old function call instead? i.e. something like:
void communicate()
{
QString theAnswer; // will be written to by setupMessage() unless error occurs
if (client.setUpMessage(theAnswer))
{
reactToAnswer(theAnswer);
client.sendMessage("HelloWorld");
}
}
The reason that signals-and-slots aren't a good fit is that signals are designed to be connectable to multiple slots at once, and the order in which the slots-methods are called is undefined -- so if a slot-method tries to interfere with the signal-emitting process in the way you describe, the behavior is rather unpredictable (because you don't know how many other connected slot-methods, if any, had already been called as part of the signal-emission, before your particular slot-method hit the brakes). And of course if you ever go to queued/asynchronous signals, then it won't work at all, because the slot will be called in a different context entirely, long after the signal-emitting function has already returned.
That said, if you absolutely must use signals-and-slots for this, you can have your slot emit its own error-has-occurred signal, which can be connected back to a slot in the original signal-emitting class. That slot could then set a boolean (or whatever), and your communicate() method could then check the state of that boolean (right after client.setUpMessage() has returned) to decide whether or not to continue executing or return early.
(I don't recommend that though -- signals-and-slots are there to make your program less complicated, and in this case I think using them instead of a regular function call actually makes your program more complicated, with no corresponding benefit)

How to call slot without connection? [duplicate]

This question already has answers here:
How to execute a functor or a lambda in a given thread in Qt, GCD-style?
(5 answers)
Closed 6 years ago.
I want to call object's slot in its own thread. In other word, to put slot processing into receiver's thread queue.
As I know, it could be done by using
QMetaObject::invokeMethod(objPtr, "someMethod", Qt:: QueuedConnection);
But as for me, this way is unsafe. Because there are no any compile-time checks about existence of method with such name. And in case of some mistype, error will occur only in runtime and only in logs.
Another way is to create dummy signal like
void callObj();
and connect this dummy signal to slot
connect(this, &Obj1::callObj, objPtr, &Obj2::someMethod, Qt:: QueuedConnection);
But this way is looks really bad.
So is there any way to do this?
Thanks in advance for help.
If you have definition of the interface you'll be calling against, you can use a single shot QTimer with 0ms timeout:
QTimer::singleShot(0, obj, &Class::slot);
you can also call it with a lambda
QTimer::singleShot(0, obj, [obj]{ obj->slot(42); } );
This approach requires the target thread to run its own event loop (i.e. QThread::exec()), but since you want to run slots in its thread I assume that's what you want.
It is not unsafe - nothing bad will happen, invokeMethod() will return false if the method doesn't exist. Check the return value to decide further course of action. It won't crash or anything like that.
You can use qobject_cast to make sure your pointer is of the right type, which should be enough to verify if it has the particular method. Other than that, take care not to mistype it and don't use untested code.
Also, consider that there are several other ways to leverage multithreading besides the implicit object thread affinity.
I wouldn't call the dummy signal approach "really bad" - it is just a hack, and hacks go hand in hand with Qt, as huge as the framework might be, it is far from fullproof.

Are signals and slots syntactic sugar or there is more to them?

I'm learning Qt and I'm having lots of fun with the signals-slotpattern. The question that I have is that, are signals and slots simply syntactic sugar for event listeners and handlers or what happens in the background is of different nature? If the later, what is the fundamental difference?
This is not just syntactic sugar. There is a real work in the background of Qt signals/slots. This work is done by the MOC (Meta-Object Compiler). This is the reason there is a process on all of your C++ header files that contains class with Q_OBJECT macros.
The "hard part" of signals/slots is when you are in a multithreading context. Indeed, the Qt::ConnectionType argument of connect() function, which is Direct (e.g. direct call of the function) in a single-threaded environment, is Queued in a if sender and emitter aren't in the same thread. In this case, the signal must be handled by the Qt event loop.
For more details: http://qt-project.org/doc/qt-4.8/signalsandslots.html
Are signals and slots syntactic sugar or there is more to them? The question that I have is that, are signals and slots simply syntactic sugar for event listeners/handlers
No, the mean reason for their existence is decoupling of the emission and handling.
or what happens in the background is of different nature?
The idea is that you separate the emission from the handling of a certain "event". If you consider the direct function calls as an alternative, I would like to point that out, with them, the code responible for the emission would need to be aware of the code that actually handles the "signal". That is the two parts would be too tight too each other.
It would not be possible to dynamically add another handler for the signal without changing the code that is responsible for the signal emission. Imagine an example like this:
Some part of the code emits a signal "fruit arrived"
This code would directly call the "wash fruit" method.
What if someone would like to add a method to count the number of fruits?
The previous code would need to be modified to include the direct call to that method.
With the signal-slot mechanism, you would not need to touch the original code. You could just simple connect your new slot to the existing signal from an entirely different piece of code. This is called good design and freedom.
This is especially useful when you have libraries like Qt that can emit signals all around without knowing about the Qt applications in advance. It is up to the Qt applications how to handle the signals, on their own.
In addition, this pattern also makes the application more responsive and less blocking, which would be the case with direction function calls. This is because of the existence of the event loop on which the Qt signal-slot mechanism is built upon. Surely, you could use threading with direct calls, too, but it becomes a lot more work and difficult to maintain than it would be necessary in an ideal world.
So, as partially already touched, there is a QtEventLoop in the background queuing up these events for processing, although it is possible to execute "direct calls", too.
The really background internal implementation code can be found there, and in moc (meta object compiler). Moc is basically creating a function for signals which you do not define a body for, so you just declare them in the QObject subclasses when you need it.
You can read more upon the topic in here, but I think my explanation could get you going:
Qt Signals & Slots
QtDD13 - Olivier Goffart - Signals and Slots in Qt 5
How Qt Signals and Slots Work
How Qt Signals and Slots Work - Part 2 - Qt5 New Syntax
Signals and Slots in Qt5
Using the Meta-Object Compiler (moc)
The signals and slots are a way to decouple the method call from the called method. They are not syntactic sugar at all since they add no new syntax to the C++ language. A signal emission is a method call. A slot is a plain old instance method. The code that links the two is plain old C++. Nothing new here - no sugar of any kind.
Most of what you call "the syntactic sugar" is akin to comments - those are empty defines (Q_SLOT, Q_SIGNAL, signals, slots) used to mark the methods for processing by the meta object compiler (moc). Moc generates introspection information and signal implementations based on normal C++ syntax of the declarations (with some limitations).
I claim that this is not syntactic sugar since moc understands regular C++ and generates introspection data based not on any syntactic sugar, but on usual instance method declarations. The "sugar" is there to avoid the premature pessimization of having moc generate metadata for everything in a class's declaration. It also lets moc ignore the method definitions - otherwise it'd need to parse them, and assume that methods without definitions are signals.
The emit macro is only for human consumption and is merely an indication that a method call is really a signal emission. It's not used by moc. It's defined to be empty.
The Q_OBJECT and Q_GADGET macros declare some class members used to access the metadata. They are, arguably, the only piece of real "sugar" since it saves you from having to type out a few lines of declarations.
There's quite a bit of code potentially involved in making it work.
A signal:
is an instance method whose implementation is generated by moc,
has full introspection information about its name and arguments. This is available as an instance of QMetaMethod.
A slot:
is an instance method whose implementation you provide,
similarly has full introspection information.
The metainformation is available at runtime and can be enumerated and used by code that has no prior knowledge of the signal's nor slot's signature.
When you emit a signal, you simply call the method generated by moc. This method invokes Qt library code that acquires relevant mutexes, iterates the list of attached slots, and executes the calls, acquiring additional mutexes as needed along the way. Doing this properly requires care, since the sender and receiver objects can reside in different threads. One has to avoid delivery of slot calls to non-existent objects. Oh, you don't want deadlocks either. This requires some forethought.
Since both signals and slots are just methods, you can certainly connect signals to other signals - the underlying mechanism doesn't care what gets called, it's just an invokable method. Non-invokable methods are those without metadata.
A slot gets invoked when the relevant signal is emitted. A signal emission is just a method call to the generated body of the signal. This is different from event-listener pattern, since the slot invocation can be either immediate (so-called direct connection) or deferred to the event loop (so-called queued connection). A queued slot call is implemented by copying the arguments and bundling them in a QMetaCallEvent. This event is "converted" back into a method call by QObject::event. This happens when the event loop delivers the event to the target object.
The metadata contains more than just signal and slot signatures. It also allows you to default- and copy-construct signal/slot parameter types - this is necessary to implement the queued calls. It also contains key-value pairs for enumerations - that's what makes Qt rather easy to script. All enum values passed to Qt methods can be looked up by name, at runtime!

How to monitor Qt main queue length?

Is there a clean way to check on the current size of Qt's main application queue? Since I'm emit'ing quite a bit of signals, I'd like to monitor how big of a delay there is in processing the slot's on the Ui thread.
For example, after:
emit Signal();
emit Signal();
emit Signal();
I'd expect to be able to call something like this, which would tell me how many of those Signals are still left to process.
QApplication::checkQueueSize();
Just to followup, I've decided to go with a solution that instead will allow me to measure the latency through the queue. As multiple people pointed out, there is no real use-case for looking at queue size.
I've implemented this by mapping a timestamp from before "emit Signal" to after the slot gets called.
Imo, it should be possible (if only for logging/tracing purposes) to get information about a QThread's event queue size.
It's possible to get the size of the postEventList for a particular thread using the following snippet:
#include <QThread>
#include <private/qthread_p.h>
int getEventQueueSize(QThread* thread)
{
auto threadData = QThreadData::get2(thread);
QMutexLocker locker(&threadData->postEventList.mutex);
return threadData->postEventList.size();
}
You need to take special care w.r.t. the used include paths, because the paths to private/qthread_p.h and private/qobject_p.h need to be provided. So in addition to the usual includes, you need to add:
g++ ... -isystem /usr/include/qt5/QtCore/5.7.1/QtCore ...
Disclaimer: Use at your own risk. Since this touches the internals of Qt, and is probably unintended use, take extra care when using this. There may be a chance for a deadlock when the postEventList.mutex is locked (as in the above example). Also note that QVector is not threadsafe (postEventList is a QVector) and postEventList.mutex is non-recursive.
You probably already know that there's the QApplication::hasPendingEvents() from QAbstractEventDispatcher.
This is for Qt4, but after taking a quick look at the Qt5 source it looks like it's still not available:
How to intercept ALL signals emitted by a given event in QT?

In Qt (4.6), is it ok to call slots directly?

I found myself in the need of having to call a slot directly. I think it's perfectly fine doing it as long as it makes sense in your design. What do you think?
Thanks
Yes.. Slots are just normal functions and you can call them directly..
From docs,
A slot is called when a signal connected to it is emitted. Slots are normal C++ functions and can be called normally; their only special feature is that signals can be connected to them.