Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-79020

QCoreApplication::processEvents() does not process queued events

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • 5.12.5
    • Core: Event loop
    • None
    • Linux/X11

    Description

      Consider the following example:

          #include <QtCore/QAbstractEventDispatcher>
          #include <QtCore/QCoreApplication>
          #include <QtCore/QDebug>
          
          QAtomicInt done = 0;
          
          void E1();
          void E2();
          void E3();
          
          void E1() {
              qDebug() << "E1";
              QMetaObject::invokeMethod(qApp, &E2, Qt::QueuedConnection);
              QMetaObject::invokeMethod(qApp, &E3, Qt::QueuedConnection);
          }
          
          void E2() {
              qDebug() << "E2";
              while (done == 0) {
                  QCoreApplication::processEvents();
              }
              QCoreApplication::exit(0);
          }
          
          void E3() {
              // We never reach this
              qDebug() << "E3";
              done = 1;
          }
          
          int main(int argc, char *argv[])
          {
              QCoreApplication app(argc, argv);
              QMetaObject::invokeMethod(qApp, &E1, Qt::QueuedConnection);
              app.exec();
          }
      

      As soon as some other thread posts an event E4 to the current event loop, E3 will be executed, followed by E4 as expected.

      This is what happens:

      1. Posted events will increase a counter (serial number) in the glib event dispatcher
      2. Before a call into QCoreApplication::sendPostedEvents, the dispatcher stores the current counter value (lastSerialNumber). If multiple events are sitting in the event queue, the counter value will reflect the last posted event.
      3. Explicit periodic calls to QCoreApplication::processEvents() go into QEventDispatcherGlib::processEvents() which invokes an iteration in the glib event loop. So far so good.
      4. The glib event loop now calls postEventSourcePrepare() which compares the stored lastSerialNumber to the current serial number. This function acts as a filter to decide whether the glib event loop should invoke QCoreApplicationPrivate::sendPostedEvents(). Since it finds lastSerialNumber to be equal to the current serial number, it doesn't do anything.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              thiago Thiago Macieira
              rweickelt Richard Weickelt
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes