Queued signals / slots help
I’m trying to debug a problem where I’m using signals/slots to send data from the UI thread to a worker and back again. This works fine on a PC, but on an embedded system it occasionally locks up (no slots called in the worker thread) until the application is minimised and then it starts again. My guess is that I’m sending events faster than they can be processed and am filling up something somewhere.
I can’t actually debug on the target, but I was wondering if there’s a way of seeing the content of the queued signals, and also seeing if a threads event loop is running. One thing I do know is that the UI event loop is still working and the emit calls are also working.
Sorry for being a bit vague, but any ideas?
It is always a good idea to limit the communication between threads to a minimum. That will improve performance and reduce the chance of deadlocks. Perhaps you should re-evaluate if you really need the amount of messages you send between the threads. Since you’re talking about the GUI, do you really need more than, say, 25 messages per second tops?
It is quite easy to swamp the message queues with queued signals and slots.
Andre: We should only be doing updates every second, but I’ve just found an infinte loop where one call is emit’ing everytime it receives a notification so that could result in more updates. What happens when the queue is swamped? Is there a maximum length beyond which events are dropped or does the queue keep growing?
Blex: Thanks for that, I’ll give that a go.
AFAIK, what happens is that also other events in the queue start to get delayed: redraws, mouse events, keyboard events, timers, network handling… That could really damage the performance of your app.
I don’t know if eventually events will be dropped, or that the queue simply grows on untill you run out of memory, but you probably don’t want to experience it either way.
Make sure you are not getting into a UI update loop; if you’ve overloaded the event functions, pay special attention there.
processEvents() is often evil, because it can result in (pseudo-)recursion. Beware, beware!
Try using QSignalSpy for your debugging – that will let you hook particular signals, but not globally.
Oh! For that matter…
If you’re using GCC (on any platform), there’s a neat hack you can use… there’s a function called __cyg_profile_func_enter (and a matching _exit) which, if you pass -finstrument-functions to GCC, wil be called at the beginning and end of every function compiled with that switch.
There’s a great summary and little “library” that got posted to Linux Gazette, [linuxgazette.net] called CTrace. I’ve used it before, and while it may not trace Qt signals, it may show you where you’re stuck.
Well after some quick learning about QSignalSpy (which is very neat!) I’ve managed to instrument everything and there’s something weird going on… It seems that the worker thread stops processing signals/slots at some point during the run, nothing is blocking in the thread as far as I can tell and if the worker thread has a simple QTimer in it the signals keep being processed! I think it’s an underlying WinCE problem but it’s very odd!
Anyway, thanks for the help above.