Skip to content

Commit

Permalink
tst_qeventdispatcher: fix UB in single-shot timers activation
Browse files Browse the repository at this point in the history
Any of these timers must be stopped before the corresponding test
function completes. Otherwise, functors will operate on dangling
pointers, which can lead to failures or unreliability of other tests.

Fix this by setting a correct context in the QTimer::singleShot()
call.

Change-Id: Icd23f6d9a2c6e7f33495d6badc4080a1b10c19f8
Reviewed-by: Volker Hilsheimer <[email protected]>
Reviewed-by: Mårten Nordheim <[email protected]>
Reviewed-by: Oswald Buddenhagen <[email protected]>
(cherry picked from commit a93f07e)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
  • Loading branch information
Alex Trotsenko authored and Qt Cherry-pick Bot committed Jan 18, 2022
1 parent f35a835 commit 701d5fd
Showing 1 changed file with 6 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ void tst_QEventDispatcher::postedEventsPingPong()

// We should use Qt::CoarseTimer on Windows, to prevent event
// dispatcher from sending a posted event.
QTimer::singleShot(500, Qt::CoarseTimer, [&mainLoop]() {
QTimer::singleShot(500, Qt::CoarseTimer, &mainLoop, [&mainLoop]() {
mainLoop.exit(1);
});

Expand All @@ -388,12 +388,12 @@ void tst_QEventDispatcher::eventLoopExit()
// Imitates QApplication::exec():
QEventLoop mainLoop;
// The test itself is a lambda:
QTimer::singleShot(0, [&mainLoop]() {
QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
// Two more single shots, both will be posted as events
// (zero timeout) and supposed to be processes by the
// mainLoop:

QTimer::singleShot(0, [&mainLoop]() {
QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
// wakeUp triggers QCocoaEventDispatcher into incrementing
// its 'serialNumber':
mainLoop.wakeUp();
Expand All @@ -402,7 +402,7 @@ void tst_QEventDispatcher::eventLoopExit()
QCoreApplication::processEvents();
});

QTimer::singleShot(0, [&mainLoop]() {
QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
// With QCocoaEventDispatcher this is executed while in the
// processEvents (see above) and would fail to actually
// interrupt the loop.
Expand All @@ -411,7 +411,7 @@ void tst_QEventDispatcher::eventLoopExit()
});

bool timeoutObserved = false;
QTimer::singleShot(500, [&timeoutObserved, &mainLoop]() {
QTimer::singleShot(500, &mainLoop, [&timeoutObserved, &mainLoop]() {
// In case the QEventLoop::exit above failed, we have to bail out
// early, not wasting time:
mainLoop.exit();
Expand All @@ -434,7 +434,7 @@ void tst_QEventDispatcher::interruptTrampling()
auto dispatcher = eventDispatcher();
QVERIFY(dispatcher);
dispatcher->processEvents(QEventLoop::AllEvents);
QTimer::singleShot(0, [dispatcher]() {
QTimer::singleShot(0, dispatcher, [dispatcher]() {
dispatcher->wakeUp();
});
dispatcher->processEvents(QEventLoop::WaitForMoreEvents);
Expand Down

0 comments on commit 701d5fd

Please sign in to comment.