[Interest] Expected event execution order in this multi-thread application
richard at weickelt.de
Mon Sep 30 10:33:12 CEST 2019
>> - Thread T1 is handling an event E1
>> - Thread T1 sends E3 to itself (queued connection)
>> - Thread T2 sends an event E2 to T1 (queued connection)
>> - Thread T1 handles E3 after completing E1.
>> - Thread T1 while handling E3 calls QCoreApplication::processEvents()
>> - E2 is sitting in the event queue of T1 at the second position but gets
>> never executed.
> How do you know that?
Because I attached a debugger and stopped T1 during QCoreApplication::processEvents(). I can see E3 (the one that the thread is currently processing) in postEventList at index 0 and E2 at index 1. That's it.
>From there I see the following call chain QEventDispatcherGlib::processEvents() followed by emit awake() because canWait is false. I haven't traced it further. The signal emission doesn't have any consequence in the event loop though.
> There's still a lack of synchronisation between T1
> calling processEvents() and T2 posting the event. What if the event was posted
> after you called it?
Then I would expect the event to be handled by the next invocation of QCoreApplication::processEvents().
> Anyway, DON'T use processEvents(). Redesign your code.
It's unfortunately QScriptEngine which calls this method, triggered by a periodic timer. The application is Qbs and it is blackboxtest::concurrentExecution which triggers that behavior. It processes a long-running script that expects a file to appear in the file system produced by another thread. But for this to happen, the current execution thread needs to handle events. The testcase usually behaves as expected, but in rare cases it doesn't and that is what I am currently investigating. https://bugreports.qt.io/browse/QBS-1499 Before I suggest an action, I want to understand the error.
>> Sure, but I don't see a synchronization problem as long if
>> QCoreApplication::processEvents() would do what the documentation says:
>> executing pending events in the current thread. Am I misunderstanding
> ALREADY pending events.
Yeah, sure, but I have already said that QCoreApplication::processEvents() is called periodically. I don't care on which invocation E2 is handled.
> Anyway, this is when you should use processEvents(): never.
It is a public API and it is not marked as deprecated. If the function does not behave as documented, then either the documentation is wrong or the implementation has a bug or I am using it the wrong way. I don't think the latter is the case, but maybe I need a minimal test case to prove that.
More information about the Interest