diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-03-29 20:25:45 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-03-30 19:17:25 +0200 |
commit | fc319a8f8b030af82613a79959d95ae800d1b2c9 (patch) | |
tree | 5d532db029a2e1bd36f8013c196978bb765869a0 /tests/auto/corelib | |
parent | 816ca43b88893e06ea866c3edadd0ca26f64b533 (diff) |
Fix QTimer::crossThreadSingleShotToFunctor test
Amends 4d90c4e74a6aa34d5aabfb91ec304da1f02df3e3, after which the test
became flaky. We need to wait for the functor to be called before
quitting the thread, otherwise we have no guarnatee that any of the
queued metacall events have been processed by the thread. Since
QThread::quit is thread-safe, we can just call it from within the
functor. This guarantees that at least one of the single-shot timers
is processed before we quit.
And since QTimer::singleShot has special code paths for 0-ms timers
(going through an explicitly queued QMetaObject::invokeMethod call
rather than through an actual QSingleShotTimer object), we need to run
the test logic with different timeouts to cover both code paths.
Task-number: QTBUG-112162
Pick-to: 6.5 6.2 5.15
Change-Id: Ide1e7b4b74dcbda72144a0d73ef5f64b0694ddbc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r-- | tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index 5c39fc5d91..2e86d89923 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -56,6 +56,7 @@ private slots: void singleShotToFunctors(); void singleShot_chrono(); void singleShot_static(); + void crossThreadSingleShotToFunctor_data(); void crossThreadSingleShotToFunctor(); void timerOrder(); void timerOrder_data(); @@ -1007,28 +1008,39 @@ void tst_QTimer::postedEventsShouldNotStarveTimers() struct DummyFunctor { static QThread *callThread; - void operator()() { callThread = QThread::currentThread(); } + void operator()() { + callThread = QThread::currentThread(); + callThread->quit(); + } }; QThread *DummyFunctor::callThread = nullptr; +void tst_QTimer::crossThreadSingleShotToFunctor_data() +{ + QTest::addColumn<int>("timeout"); + + QTest::addRow("zero-timer") << 0; + QTest::addRow("1ms") << 1; +} + void tst_QTimer::crossThreadSingleShotToFunctor() { + QFETCH(int, timeout); // We're also testing for crashes here, so the test simply running to // completion is part of the success + DummyFunctor::callThread = nullptr; + QThread t; t.start(); - QObject* o = new QObject(); + std::unique_ptr<QObject> o(new QObject()); o->moveToThread(&t); - DummyFunctor::callThread = nullptr; - for (int i = 0; i < 10000; i++) { - QTimer::singleShot(0, o, DummyFunctor()); - } + for (int i = 0; i < 10000; i++) + QTimer::singleShot(timeout, o.get(), DummyFunctor()); - t.quit(); t.wait(); - delete o; + o.reset(); QCOMPARE(DummyFunctor::callThread, &t); } |