[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