Attempt to unwedge tst_QThread::wait3_slowDestructor()

When the test failed, it never released the blocking slot, so the
tested thread remained blocked indefinitely. Blacklisting doesn't
rescue that: the test run gets killed by Coin's watchdog.

Use a QScopeGuard() to release the clocked slot on failure.
replacing the release that was happening only on success.

As drive-by clean-up, smarten up the code a little and remove an
unused enum.

Pick-to: 6.2 6.1 5.15
Change-Id: Ie035dafe6e4b1d82aea5de38ceb31c0f7fcf81d7
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
Edward Welbourne 2021-08-11 09:49:11 +02:00
parent ebcc8413f2
commit 2684deaf26

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@ -40,6 +40,7 @@
#include <qwaitcondition.h>
#include <qdebug.h>
#include <qmetaobject.h>
#include <qscopeguard.h>
#ifdef Q_OS_UNIX
#include <pthread.h>
@ -1086,8 +1087,8 @@ void tst_QThread::wait2()
qPrintable(msgElapsed(elapsed)));
}
class SlowSlotObject : public QObject {
class SlowSlotObject : public QObject
{
Q_OBJECT
public:
QMutex mutex;
@ -1103,22 +1104,23 @@ void tst_QThread::wait3_slowDestructor()
{
SlowSlotObject slow;
QThread thread;
QObject::connect(&thread, SIGNAL(finished()), &slow, SLOT(slowSlot()), Qt::DirectConnection);
enum { WaitTime = 1800 };
QObject::connect(&thread, &QThread::finished,
&slow, &SlowSlotObject::slowSlot, Qt::DirectConnection);
QElapsedTimer timer;
thread.start();
thread.quit();
//the quit function will cause the thread to finish and enter the slowSlot that is blocking
// Calling quit() will cause the thread to finish and enter the blocking slowSlot().
timer.start();
QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
qint64 elapsed = timer.elapsed();
QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 1, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
slow.cond.wakeOne();
//now the thread should finish quickly
{
// Ensure thread finishes quickly after the checks - regardless of success:
QScopeGuard wakeSlow([&slow]() -> void { slow.cond.wakeOne(); });
QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
const qint64 elapsed = timer.elapsed();
QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 1,
qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
}
QVERIFY(thread.wait(one_minute));
}