Remove QThreadPool::cancel()
Deprecated in 5.9 Change-Id: Ib6e2a5da1e7ee2664fb6fa496bdc880fab870901 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
458d49861f
commit
999c79863c
@ -52,9 +52,7 @@ class Q_CORE_EXPORT QRunnable
|
|||||||
friend class QThreadPool;
|
friend class QThreadPool;
|
||||||
friend class QThreadPoolPrivate;
|
friend class QThreadPoolPrivate;
|
||||||
friend class QThreadPoolThread;
|
friend class QThreadPoolThread;
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
Q_DISABLE_COPY(QRunnable)
|
Q_DISABLE_COPY(QRunnable)
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
|
||||||
|
@ -786,24 +786,6 @@ bool QThreadPool::contains(const QThread *thread) const
|
|||||||
return d->allThreads.contains(const_cast<QThreadPoolThread *>(poolThread));
|
return d->allThreads.contains(const_cast<QThreadPoolThread *>(poolThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_DEPRECATED_SINCE(5, 9)
|
|
||||||
/*!
|
|
||||||
\since 5.5
|
|
||||||
\obsolete use tryTake() instead, but note the different deletion rules.
|
|
||||||
|
|
||||||
Removes the specified \a runnable from the queue if it is not yet started.
|
|
||||||
The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()}
|
|
||||||
returns \c true are deleted.
|
|
||||||
|
|
||||||
\sa start(), tryTake()
|
|
||||||
*/
|
|
||||||
void QThreadPool::cancel(QRunnable *runnable)
|
|
||||||
{
|
|
||||||
if (tryTake(runnable) && runnable->autoDelete() && !runnable->ref) // tryTake already deref'ed
|
|
||||||
delete runnable;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "moc_qthreadpool.cpp"
|
#include "moc_qthreadpool.cpp"
|
||||||
|
@ -95,10 +95,6 @@ public:
|
|||||||
|
|
||||||
bool contains(const QThread *thread) const;
|
bool contains(const QThread *thread) const;
|
||||||
|
|
||||||
#if QT_DEPRECATED_SINCE(5, 9)
|
|
||||||
QT_DEPRECATED_X("use tryTake(), but note the different deletion rules")
|
|
||||||
void cancel(QRunnable *runnable);
|
|
||||||
#endif
|
|
||||||
Q_REQUIRED_RESULT bool tryTake(QRunnable *runnable);
|
Q_REQUIRED_RESULT bool tryTake(QRunnable *runnable);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,9 +93,6 @@ private slots:
|
|||||||
void priorityStart();
|
void priorityStart();
|
||||||
void waitForDone();
|
void waitForDone();
|
||||||
void clear();
|
void clear();
|
||||||
#if QT_DEPRECATED_SINCE(5, 9)
|
|
||||||
void cancel();
|
|
||||||
#endif
|
|
||||||
void tryTake();
|
void tryTake();
|
||||||
void waitForDoneTimeout();
|
void waitForDoneTimeout();
|
||||||
void destroyingWaitsForTasksToFinish();
|
void destroyingWaitsForTasksToFinish();
|
||||||
@ -976,80 +973,6 @@ void tst_QThreadPool::clear()
|
|||||||
QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount());
|
QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_DEPRECATED_SINCE(5, 9)
|
|
||||||
void tst_QThreadPool::cancel()
|
|
||||||
{
|
|
||||||
QSemaphore sem(0);
|
|
||||||
QSemaphore startedThreads(0);
|
|
||||||
|
|
||||||
class BlockingRunnable : public QRunnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QSemaphore & sem;
|
|
||||||
QSemaphore &startedThreads;
|
|
||||||
QAtomicInt &dtorCounter;
|
|
||||||
QAtomicInt &runCounter;
|
|
||||||
int dummy;
|
|
||||||
|
|
||||||
explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
|
|
||||||
: sem(s), startedThreads(started), dtorCounter(c), runCounter(r){}
|
|
||||||
|
|
||||||
~BlockingRunnable()
|
|
||||||
{
|
|
||||||
dtorCounter.fetchAndAddRelaxed(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
startedThreads.release();
|
|
||||||
runCounter.fetchAndAddRelaxed(1);
|
|
||||||
sem.acquire();
|
|
||||||
count.ref();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
MaxThreadCount = 3,
|
|
||||||
OverProvisioning = 2,
|
|
||||||
runs = MaxThreadCount * OverProvisioning
|
|
||||||
};
|
|
||||||
|
|
||||||
QThreadPool threadPool;
|
|
||||||
threadPool.setMaxThreadCount(MaxThreadCount);
|
|
||||||
BlockingRunnable *runnables[runs];
|
|
||||||
|
|
||||||
// ensure that the QThreadPool doesn't deadlock if any of the checks fail
|
|
||||||
// and cause an early return:
|
|
||||||
const QSemaphoreReleaser semReleaser(sem, runs);
|
|
||||||
|
|
||||||
count.storeRelaxed(0);
|
|
||||||
QAtomicInt dtorCounter = 0;
|
|
||||||
QAtomicInt runCounter = 0;
|
|
||||||
for (int i = 0; i < runs; i++) {
|
|
||||||
runnables[i] = new BlockingRunnable(sem, startedThreads, dtorCounter, runCounter);
|
|
||||||
runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not
|
|
||||||
threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue
|
|
||||||
threadPool.start(runnables[i]);
|
|
||||||
}
|
|
||||||
// wait for all worker threads to have started up:
|
|
||||||
QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */));
|
|
||||||
|
|
||||||
for (int i = 0; i < runs; i++) {
|
|
||||||
threadPool.cancel(runnables[i]);
|
|
||||||
}
|
|
||||||
runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs
|
|
||||||
runnables[runs-1]->dummy = 0;
|
|
||||||
QCOMPARE(dtorCounter.loadRelaxed(), runs - threadPool.maxThreadCount() - 1);
|
|
||||||
sem.release(threadPool.maxThreadCount());
|
|
||||||
threadPool.waitForDone();
|
|
||||||
QCOMPARE(runCounter.loadRelaxed(), threadPool.maxThreadCount());
|
|
||||||
QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount());
|
|
||||||
QCOMPARE(dtorCounter.loadRelaxed(), runs - 2);
|
|
||||||
delete runnables[0]; //if the pool deletes them then we'll get double-free crash
|
|
||||||
delete runnables[runs-1];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void tst_QThreadPool::tryTake()
|
void tst_QThreadPool::tryTake()
|
||||||
{
|
{
|
||||||
QSemaphore sem(0);
|
QSemaphore sem(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user