From 5b11e43e9f7551b9cb1ea7a6effdcab4bfa6b8c9 Mon Sep 17 00:00:00 2001 From: Nick Shaforostoff Date: Mon, 16 Jun 2014 18:50:12 +0300 Subject: QThreadPool::cancel() to remove individual jobs from the job queue. [ChangeLog][QtCore][QThreadPool] Added QThreadPool::cancel() which allows removing from the job queue a job that hasn't been started yet. Change-Id: Ib8f1c1f32a34f5eec8338c641d820b928e470164 Reviewed-by: Nick Shaforostoff Reviewed-by: Olivier Goffart --- src/corelib/thread/qfutureinterface.cpp | 4 +-- src/corelib/thread/qthreadpool.cpp | 44 ++++++++++++++++++++++++++------- src/corelib/thread/qthreadpool.h | 1 + src/corelib/thread/qthreadpool_p.h | 3 ++- 4 files changed, 40 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 1f417d3d74..a23c32a73b 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -292,7 +292,7 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) // To avoid deadlocks and reduce the number of threads used, try to // run the runnable in the current thread. - d->pool()->d_func()->stealRunnable(d->runnable); + d->pool()->d_func()->stealAndRunRunnable(d->runnable); lock.relock(); @@ -313,7 +313,7 @@ void QFutureInterfaceBase::waitForFinished() lock.unlock(); if (!alreadyFinished) { - d->pool()->d_func()->stealRunnable(d->runnable); + d->pool()->d_func()->stealAndRunRunnable(d->runnable); lock.relock(); diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 2a7cb8d66b..aaffdc2a4c 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -311,14 +311,12 @@ void QThreadPoolPrivate::clear() /*! \internal Searches for \a runnable in the queue, removes it from the queue and - runs it if found. This function does not return until the runnable - has completed. + returns \c true if it was found in the queue */ -void QThreadPoolPrivate::stealRunnable(QRunnable *runnable) +bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable) { if (runnable == 0) - return; - bool found = false; + return false; { QMutexLocker locker(&mutex); QList >::iterator it = queue.begin(); @@ -326,17 +324,26 @@ void QThreadPoolPrivate::stealRunnable(QRunnable *runnable) while (it != end) { if (it->first == runnable) { - found = true; queue.erase(it); - break; + return true; } ++it; } } - if (!found) - return; + return false; +} + /*! + \internal + Searches for \a runnable in the queue, removes it from the queue and + runs it if found. This function does not return until the runnable + has completed. + */ +void QThreadPoolPrivate::stealAndRunRunnable(QRunnable *runnable) +{ + if (!stealRunnable(runnable)) + return; const bool autoDelete = runnable->autoDelete(); bool del = autoDelete && !--runnable->ref; @@ -628,6 +635,25 @@ void QThreadPool::clear() d->clear(); } +/*! + \since 5.5 + + 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() +*/ +void QThreadPool::cancel(QRunnable *runnable) +{ + Q_D(QThreadPool); + if (!d->stealRunnable(runnable)) + return; + if (runnable->autoDelete() && !--runnable->ref) { + delete runnable; + } +} + QT_END_NAMESPACE #endif diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index e4d23cc200..c8cc5dfd89 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -77,6 +77,7 @@ public: bool waitForDone(int msecs = -1); void clear(); + void cancel(QRunnable *runnable); }; QT_END_NAMESPACE diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index d4308266a2..de2727adc1 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -76,7 +76,8 @@ public: void reset(); bool waitForDone(int msecs); void clear(); - void stealRunnable(QRunnable *); + bool stealRunnable(QRunnable *runnable); + void stealAndRunRunnable(QRunnable *runnable); mutable QMutex mutex; QSet allThreads; -- cgit v1.2.3