[vlc-commits] [Git][videolan/vlc][master] contrib: qtbase: QEventDispatcherWin32: fix livelock and allow overriding posted event batch size

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Thu May 21 16:48:53 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
96864b4e by Fatih Uzunoglu at 2026-05-21T18:21:26+02:00
contrib: qtbase: QEventDispatcherWin32: fix livelock and allow overriding posted event batch size

If we are not sending all posted events, we should not kill the posted events timer
or allow posting `WM_QT_SENDPOSTEDEVENTS` since doing so causes livelock when modal
event loops are involved in certain situations (such as resizing the window).

I could not reproduce this problem with Windows 10 (VM) and 8 (VM), but on my main
Windows 11 system it happens often when there are pending events waiting to be
processed, which is a concern especially when playing a content, since in this case
Qt has a lot of events to process constantly.

This change also introduces possibility to override the batch size with an environment
variable (`QT_POSTEDEVENTS_BATCH`). Setting it a negative value prevents fair treatment
of posted events when the event dispatcher is busy (essentially negating our patch),
while setting it to 0 will process all backlogged events. Note that while permitted,
setting it to 0 may cause livelock. The default value is 32.

I have tested this patch on non-VM up-to-date Windows 11.

Regression since 1c3a7c20.

- - - - -


1 changed file:

- contrib/src/qt/0001-QEventDispatcherWin32-treat-posted-events-fairly.patch


Changes:

=====================================
contrib/src/qt/0001-QEventDispatcherWin32-treat-posted-events-fairly.patch
=====================================
@@ -1,4 +1,4 @@
-From c60305a7564c63c9e175ba65e721df1db6855251 Mon Sep 17 00:00:00 2001
+From a3dc9de7966221e1bae1246fbb0a67bf7a5d2a34 Mon Sep 17 00:00:00 2001
 From: Fatih Uzunoglu <fuzun54 at outlook.com>
 Date: Tue, 18 Feb 2025 23:29:57 +0200
 Subject: [PATCH] QEventDispatcherWin32: treat posted events fairly
@@ -6,19 +6,19 @@ Subject: [PATCH] QEventDispatcherWin32: treat posted events fairly
 By processing at least a batch of posted events
 while prioritizing other message types.
 ---
- src/corelib/kernel/qcoreapplication.cpp             | 10 ++++++++--
- src/corelib/kernel/qcoreapplication_p.h             |  2 +-
- src/corelib/kernel/qeventdispatcher_win.cpp         | 13 +++++++++++--
- src/corelib/kernel/qeventdispatcher_win_p.h         |  2 +-
- .../platform/windows/qwindowsguieventdispatcher.cpp |  4 ++--
- .../platform/windows/qwindowsguieventdispatcher_p.h |  2 +-
- 6 files changed, 24 insertions(+), 9 deletions(-)
+ src/corelib/kernel/qcoreapplication.cpp       | 10 ++++-
+ src/corelib/kernel/qcoreapplication_p.h       |  2 +-
+ src/corelib/kernel/qeventdispatcher_win.cpp   | 43 ++++++++++++++++---
+ src/corelib/kernel/qeventdispatcher_win_p.h   |  2 +-
+ .../windows/qwindowsguieventdispatcher.cpp    |  4 +-
+ .../windows/qwindowsguieventdispatcher_p.h    |  2 +-
+ 6 files changed, 49 insertions(+), 14 deletions(-)
 
 diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
-index 48c75973f7f..83ed71c23e9 100644
+index 0aa120ee1be..d557025399e 100644
 --- a/src/corelib/kernel/qcoreapplication.cpp
 +++ b/src/corelib/kernel/qcoreapplication.cpp
-@@ -1801,7 +1801,7 @@ void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
+@@ -1806,7 +1806,7 @@ void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
  }
  
  void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
@@ -27,7 +27,7 @@ index 48c75973f7f..83ed71c23e9 100644
  {
      if (event_type == -1) {
          // we were called by an obsolete event dispatcher.
-@@ -1873,7 +1873,13 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
+@@ -1878,7 +1878,13 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
      };
      CleanUp cleanup(receiver, event_type, data);
  
@@ -43,10 +43,10 @@ index 48c75973f7f..83ed71c23e9 100644
          if (i >= data->postEventList.insertionOffset)
              break;
 diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
-index 0a51a0b5de8..dd85bb59d2c 100644
+index ad99e2d5e0e..54282696b9c 100644
 --- a/src/corelib/kernel/qcoreapplication_p.h
 +++ b/src/corelib/kernel/qcoreapplication_p.h
-@@ -107,7 +107,7 @@ public:
+@@ -108,7 +108,7 @@ public:
      static QThread *mainThread();
      static bool threadRequiresCoreApplication();
  
@@ -56,10 +56,19 @@ index 0a51a0b5de8..dd85bb59d2c 100644
      static void checkReceiverThread(QObject *receiver);
      void cleanupThreadData();
 diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
-index 78ad3d3edeb..7c247724d09 100644
+index 78ad3d3edeb..1f9a04baea3 100644
 --- a/src/corelib/kernel/qeventdispatcher_win.cpp
 +++ b/src/corelib/kernel/qeventdispatcher_win.cpp
-@@ -37,6 +37,8 @@ QT_BEGIN_NAMESPACE
+@@ -4,6 +4,8 @@
+ 
+ #include "qeventdispatcher_win_p.h"
+ 
++#include <QtCore/qtenvironmentvariables.h>
++#include <optional>
+ #include "qcoreapplication.h"
+ #include <private/qsystemlibrary_p.h>
+ #include "qoperatingsystemversion.h"
+@@ -37,6 +39,8 @@ QT_BEGIN_NAMESPACE
  #endif
  #endif // QT_NO_GESTURES
  
@@ -68,14 +77,29 @@ index 78ad3d3edeb..7c247724d09 100644
  enum {
      WM_QT_SOCKETNOTIFIER = WM_USER,
      WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
-@@ -204,7 +206,14 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
+@@ -204,7 +208,29 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
          if (HIWORD(GetQueueStatus(mask)) == 0)
              q->sendPostedEvents();
          else
 +        {
 +            // Fair treatment for posted events,
 +            // at least process some of the pending events:
-+            q->sendPostedEvents(POSTEDEVENTS_BATCH);
++            static const auto postedEventsBatch = []() -> std::optional<int> {
++                bool ok;
++                const int batch = qEnvironmentVariableIntValue("QT_POSTEDEVENTS_BATCH", &ok);
++                if (ok) {
++                    if (batch >= 0)
++                        return batch;
++                    else
++                        return std::nullopt;
++                } else {
++                    return POSTEDEVENTS_BATCH;
++                }
++            }();
++
++            if (postedEventsBatch)
++                q->sendPostedEvents(*postedEventsBatch);
++
 +            // We still need this, because there can be more than
 +            // POSTEDEVENTS_BATCH posted events waiting to be processed:
              d->startPostedEventsTimer();
@@ -83,7 +107,7 @@ index 78ad3d3edeb..7c247724d09 100644
          return 0;
      } // switch (message)
  
-@@ -893,7 +902,7 @@ bool QEventDispatcherWin32::event(QEvent *e)
+@@ -893,18 +919,21 @@ bool QEventDispatcherWin32::event(QEvent *e)
      return QAbstractEventDispatcher::event(e);
  }
  
@@ -92,9 +116,20 @@ index 78ad3d3edeb..7c247724d09 100644
  {
      Q_D(QEventDispatcherWin32);
  
-@@ -904,7 +913,7 @@ void QEventDispatcherWin32::sendPostedEvents()
-     // Allow posting WM_QT_SENDPOSTEDEVENTS message.
-     d->wakeUps.storeRelaxed(0);
+-    if (d->sendPostedEventsTimerId != 0)
+-        KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
+-    d->sendPostedEventsTimerId = 0;
++    if (count == 0)
++    {
++        if (d->sendPostedEventsTimerId != 0)
++            KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
++        d->sendPostedEventsTimerId = 0;
+ 
+-    // Allow posting WM_QT_SENDPOSTEDEVENTS message.
+-    d->wakeUps.storeRelaxed(0);
++        // Allow posting WM_QT_SENDPOSTEDEVENTS message.
++        d->wakeUps.storeRelaxed(0);
++    }
  
 -    QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData.loadRelaxed());
 +    QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData.loadRelaxed(), count);
@@ -144,5 +179,5 @@ index 7d326c07808..d7ee009f1a0 100644
  private:
      QEventLoop::ProcessEventsFlags m_flags;
 -- 
-2.48.1
+2.53.0
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/96864b4e002135924c3c8d4daade15c9ee95b201

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/96864b4e002135924c3c8d4daade15c9ee95b201
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list