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

Queued connections are extremely slow on Windows

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.5, 6.6, 6.7, 6.8
    • Core: Event loop
    • None
    • Windows

    Description

      Unlike Linux, on Windows delayed bindings (often used in QML) are extremely slow. Since delayed bindings are used in layouting, it is very easy to notice the delays.

      Delayed bindings are:

      > A delayed binding will not immediately update the target, but rather wait until the event queue has been cleared.

      Which I assume is basically a queued connection, or a timer with 0 timeout.

      It is interesting that no one else has noticed it, as this has been around for a long time.

      I have noticed the following:

      QEventDispatcherWin32: fix posted events delivering
      
      To avoid livelocks, posted events should be delivered when all pending
      messages have been processed, and the thread's message queue becomes
      empty. Although the logic of the previous patch is correct, it turned
      out that determining the moment when the message queue is really empty
      is not so simple. It is worth noting that the GetQueueStatus function
      sometimes reports unexpected results due to internal filtering and
      processing. Indeed, Windows docs say that "the return value from
      GetQueueStatus should be considered only a hint as to whether
      GetMessage or PeekMessage should be called". Thus, we cannot rely on
      GetQueueStatus in unambiguous logic inside the qt_GetMessageHook.
      
      To solve the problem, this patch introduces a guard timer which
      guarantees low priority processing for posted events in foreign loop.
      The wakeUps flag reset logic has also been changed to provide clearer
      synchronization of the Qt internal loop.
      
      Fixes: QTBUG-82701
      Fixes: QTBUG-83151
      Change-Id: I33d5001a40d2a4879ef4eb878c09bc1c0616e289
      Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> 

      That commit introduced this change:

      // Start a timer to deliver posted events when the message queue is emptied.  
      d->sendPostedEventsTimerId = SetTimer(d->internalHwnd, SendPostedEventsTimerId,                                              USER_TIMER_MINIMUM, NULL); 

      I have checked `USER_TIMER_MINIMUM`, which is 10. 10 millisecond timeout is really generous for posted events. GUI applications almost always have stuff in the message queue, so in order to give them priority, it is not fair to discriminate the posted events with 10 millisecond delay...

      I have recorded this video to demonstrate the incurred delay on a blank QML application:

      qtcreator_9AsC4FlOod.mp4

       

      vhilshei 

      Attachments

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

        Activity

          People

            thiago Thiago Macieira
            fuzun Fatih Uzunoglu
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes