diff options
author | Igor Kushnir <igorkuo@gmail.com> | 2020-01-10 19:48:43 +0200 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2020-12-18 16:06:38 +0100 |
commit | f2d22d5a5126e7a73da620a60847fc124f724333 (patch) | |
tree | 6d240dd61f42fbe58c485871e4bf05f10fab73cc /src/plugins/platforms/xcb/qxcbeventqueue.h | |
parent | c6dde54e67d508cacf63477b313d0acdf271f44c (diff) |
xcb: fix thread synchronization in QXcbEventQueue::waitForNewEvents() again
This patch amends a41701904e880f58e19b352ade1931d6cd1a7112
If peeking into the event queue looking for a clipboard event fails,
QXcbClipboard::waitForClipboardEvent() calls queue->peek for the second
time to "process other clipboard events, since someone is probably
requesting data from us". QXcbEventQueue::peek() in turn calls
QXcbEventQueue::flushBufferedEvents(). This second flushing can acquire
a waited-for clipboard event. The issue was that the code in
waitForNewEvents() ignored this possibility and assumed that there were
no clipboard events before or at its current m_flushedTail. If there
were no more events on the X11 connection after tailBeforeFlush,
the waitForNewEvents() in waitForClipboardEvent() blocked execution
for 5 seconds and eventually timed out.
The fix is to remember QXcbEventQueue::m_flushedTail just after looking
for and not finding a clipboard event in the queue. And then wait for
more events via QWaitCondition in waitForNewEvents() only if there were
no more events after the remembered m_flushedTail.
Fixes: QTBUG-75319
Pick-to: 5.15
Pick-to: 5.12
Change-Id: I4919c5b9b9227b3a8a29a11e7094f97960b3a121
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbeventqueue.h')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbeventqueue.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h index 4763b57ecb..67a1825ead 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.h +++ b/src/plugins/platforms/xcb/qxcbeventqueue.h @@ -107,7 +107,9 @@ public: bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr, PeekOptions option = PeekDefault, qint32 peekerId = -1); - void waitForNewEvents(unsigned long time = std::numeric_limits<unsigned long>::max()); + const QXcbEventNode *flushedTail() const { return m_flushedTail; } + void waitForNewEvents(const QXcbEventNode *sinceFlushedTail, + unsigned long time = std::numeric_limits<unsigned long>::max()); private: QXcbEventNode *qXcbEventNodeFactory(xcb_generic_event_t *event); |