[Interest] PeekMessage, DispatchMessage and Qt events dispatching

Benjamin TERRIER b.terrier at gmail.com
Mon Mar 14 18:39:25 CET 2016


Hi everyone,

I have encountered the following problem on Windows:

I have 2 QThreads and 2 QObjects (each one living on one thread). One
QObject ,the sender, periodically calls a slot on the other QObject
,the receiver, with the following code:

    QMetaObject::invokeMethod(m_receiver, "work", Qt::QueuedConnection);

The work() slot on the receiver looks like this:

    void Receiver::work()
    {
        static int count = 0;
        qDebug("<work %d>", count);
        count += 1;

        doSomethingThatTakesTime();

        count -= 1;
        qDebug("</work %d>", count);
    }

The doSomethingThatTakesTime() function is long enough that during its
execution the sender has the time to make another call to the work()
slot.

The expected output would be something like:
    <work 0>
    </work 0>
    <work 0>
    </work 0>
    <work 0>
    </work 0>
    ...

However for some reason deep within the doSomethingThatTakesTime()
function there is this code (don't ask me why, it's an old piece of
code):
    if(PeekMessage(&msg, 0,0,0,PM_REMOVE))
    {
         DispatchMessage(&msg);
    }
Which changes the output as:
    <work 0>
    </work 0>
    <work 0>
    <work 1>
    </work 1>
    <work 1>
    <work 2>
    <work 3>
    </work 3>
    <work 3>
    <work 4>

It seems that when DispatchMessage is called the Qt event dispatcher
is forced to process the next event in queue even if the current event
is still being processed. Moreover the execution stack is never
unstacked i.e DispatchMessage doesn't return.

So here is my question is there a bug in Qt or does DispatchMessage
shouldn't be called ?

Regards,

Benjamin Terrier



More information about the Interest mailing list