qthreadpool.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qthreadpool.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtCore module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qthreadpool.h"-
41#include "qthreadpool_p.h"-
42#include "qelapsedtimer.h"-
43-
44#include <algorithm>-
45-
46#ifndef QT_NO_THREAD-
47-
48QT_BEGIN_NAMESPACE-
49-
50Q_GLOBAL_STATIC(QThreadPool, theInstance)-
51-
52/*-
53 QThread wrapper, provides synchronization against a ThreadPool-
54*/-
55class QThreadPoolThread : public QThread-
56{-
57public:-
58 QThreadPoolThread(QThreadPoolPrivate *manager);-
59 void run() Q_DECL_OVERRIDE;-
60 void registerThreadInactive();-
61-
62 QWaitCondition runnableReady;-
63 QThreadPoolPrivate *manager;-
64 QRunnable *runnable;-
65};-
66-
67/*-
68 QThreadPool private class.-
69*/-
70-
71-
72/*!-
73 \internal-
74*/-
75QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager)-
76 :manager(manager), runnable(0)-
77{ }-
78-
79/*-
80 \internal-
81*/-
82void QThreadPoolThread::run()-
83{-
84 QMutexLocker locker(&manager->mutex);-
85 for(;;) {-
86 QRunnable *r = runnable;-
87 runnable = 0;-
88-
89 do {-
90 if (r) {-
91 const bool autoDelete = r->autoDelete();-
92-
93-
94 // run the task-
95 locker.unlock();-
96#ifndef QT_NO_EXCEPTIONS-
97 try {-
98#endif-
99 r->run();-
100#ifndef QT_NO_EXCEPTIONS-
101 } catch (...) {-
102 qWarning("Qt Concurrent has caught an exception thrown from a worker thread.\n"-
103 "This is not supported, exceptions thrown in worker threads must be\n"-
104 "caught before control returns to Qt Concurrent.");-
105 registerThreadInactive();-
106 throw;-
107 }-
108#endif-
109 locker.relock();-
110-
111 if (autoDelete && !--r->ref)-
112 delete r;-
113 }-
114-
115 // if too many threads are active, expire this thread-
116 if (manager->tooManyThreadsActive())-
117 break;-
118-
119 r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0;-
120 } while (r != 0);-
121-
122 if (manager->isExiting) {-
123 registerThreadInactive();-
124 break;-
125 }-
126-
127 // if too many threads are active, expire this thread-
128 bool expired = manager->tooManyThreadsActive();-
129 if (!expired) {-
130 manager->waitingThreads.enqueue(this);-
131 registerThreadInactive();-
132 // wait for work, exiting after the expiry timeout is reached-
133 runnableReady.wait(locker.mutex(), manager->expiryTimeout);-
134 ++manager->activeThreads;-
135 if (manager->waitingThreads.removeOne(this))-
136 expired = true;-
137 }-
138 if (expired) {-
139 manager->expiredThreads.enqueue(this);-
140 registerThreadInactive();-
141 break;-
142 }-
143 }-
144}-
145-
146void QThreadPoolThread::registerThreadInactive()-
147{-
148 if (--manager->activeThreads == 0)-
149 manager->noActiveThreads.wakeAll();-
150}-
151-
152-
153/*-
154 \internal-
155*/-
156QThreadPoolPrivate:: QThreadPoolPrivate()-
157 : isExiting(false),-
158 expiryTimeout(30000),-
159 maxThreadCount(qAbs(QThread::idealThreadCount())),-
160 reservedThreads(0),-
161 activeThreads(0)-
162{ }-
163-
164bool QThreadPoolPrivate::tryStart(QRunnable *task)-
165{-
166 if (allThreads.isEmpty()) {-
167 // always create at least one thread-
168 startThread(task);-
169 return true;-
170 }-
171-
172 // can't do anything if we're over the limit-
173 if (activeThreadCount() >= maxThreadCount)-
174 return false;-
175-
176 if (waitingThreads.count() > 0) {-
177 // recycle an available thread-
178 enqueueTask(task);-
179 waitingThreads.takeFirst()->runnableReady.wakeOne();-
180 return true;-
181 }-
182-
183 if (!expiredThreads.isEmpty()) {-
184 // restart an expired thread-
185 QThreadPoolThread *thread = expiredThreads.dequeue();-
186 Q_ASSERT(thread->runnable == 0);-
187-
188 ++activeThreads;-
189-
190 if (task->autoDelete())-
191 ++task->ref;-
192 thread->runnable = task;-
193 thread->start();-
194 return true;-
195 }-
196-
197 // start a new thread-
198 startThread(task);-
199 return true;-
200}-
201-
202inline bool operator<(int priority, const QPair<QRunnable *, int> &p)-
203{ return p.second < priority; }-
204inline bool operator<(const QPair<QRunnable *, int> &p, int priority)-
205{ return priority < p.second; }-
206-
207void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)-
208{-
209 if (runnable->autoDelete())-
210 ++runnable->ref;-
211-
212 // put it on the queue-
213 QVector<QPair<QRunnable *, int> >::const_iterator begin = queue.constBegin();-
214 QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constEnd();-
215 if (it != begin && priority > (*(it - 1)).second)-
216 it = std::upper_bound(begin, --it, priority);-
217 queue.insert(it - begin, qMakePair(runnable, priority));-
218}-
219-
220int QThreadPoolPrivate::activeThreadCount() const-
221{-
222 return (allThreads.count()-
223 - expiredThreads.count()-
224 - waitingThreads.count()-
225 + reservedThreads);-
226}-
227-
228void QThreadPoolPrivate::tryToStartMoreThreads()-
229{-
230 // try to push tasks on the queue to any available threads-
231 while (!queue.isEmpty() && tryStart(queue.firstconstFirst().first))
!queue.isEmpty()Description
TRUEevaluated 11 times by 1 test
Evaluated by:
  • tst_QThreadPool
FALSEevaluated 49801 times by 31 tests
Evaluated by:
  • tst_Lancelot
  • tst_NetworkSelfTest
  • tst_PlatformSocketEngine
  • tst_QAbstractNetworkCache
  • tst_QDebug
  • tst_QDnsLookup
  • tst_QDnsLookup_Appless
  • tst_QFtp
  • tst_QHostInfo
  • tst_QHttpNetworkConnection
  • tst_QHttpSocketEngine
  • tst_QIODevice
  • tst_QMimeDatabase
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkInterface
  • tst_QNetworkProxyFactory
  • tst_QObject
  • tst_QProcess
  • tst_QSocks5SocketEngine
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpServer
  • tst_QTextCodec
  • ...
tryStart(queue...First().first)Description
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tst_QThreadPool
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tst_QThreadPool
2-49801
232 queue.removeFirst();
executed 9 times by 1 test: queue.removeFirst();
Executed by:
  • tst_QThreadPool
9
233}
executed 49803 times by 31 tests: end of block
Executed by:
  • tst_Lancelot
  • tst_NetworkSelfTest
  • tst_PlatformSocketEngine
  • tst_QAbstractNetworkCache
  • tst_QDebug
  • tst_QDnsLookup
  • tst_QDnsLookup_Appless
  • tst_QFtp
  • tst_QHostInfo
  • tst_QHttpNetworkConnection
  • tst_QHttpSocketEngine
  • tst_QIODevice
  • tst_QMimeDatabase
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkInterface
  • tst_QNetworkProxyFactory
  • tst_QObject
  • tst_QProcess
  • tst_QSocks5SocketEngine
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpServer
  • tst_QTextCodec
  • ...
49803
234-
235bool QThreadPoolPrivate::tooManyThreadsActive() const-
236{-
237 const int activeThreadCount = this->activeThreadCount();-
238 return activeThreadCount > maxThreadCount && (activeThreadCount - reservedThreads) > 1;-
239}-
240-
241/*!-
242 \internal-
243*/-
244void QThreadPoolPrivate::startThread(QRunnable *runnable)-
245{-
246 QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this));-
247 thread->setObjectName(QLatin1String("Thread (pooled)"));-
248 allThreads.insert(thread.data());-
249 ++activeThreads;-
250-
251 if (runnable->autoDelete())-
252 ++runnable->ref;-
253 thread->runnable = runnable;-
254 thread.take()->start();-
255}-
256-
257/*!-
258 \internal-
259 Makes all threads exit, waits for each thread to exit and deletes it.-
260*/-
261void QThreadPoolPrivate::reset()-
262{-
263 QMutexLocker locker(&mutex);-
264 isExiting = true;-
265-
266 while (!allThreads.empty()) {
!allThreads.empty()Description
TRUEevaluated 957 times by 37 tests
Evaluated by:
  • tst_QDnsLookup_Appless
  • tst_QFuture
  • tst_QHostInfo
  • tst_QPointer
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpSocket
  • tst_QTextCodec
  • tst_QThreadPool
  • tst_QtConcurrentRun
  • tst_lancelot - unknown status
  • tst_qdebug - unknown status
  • tst_qdnslookup - unknown status
  • tst_qftp - unknown status
  • tst_qfuturewatcher - unknown status
  • tst_qhostinfo - unknown status
  • tst_qhttpnetworkconnection - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qlockfile - unknown status
  • tst_qmimedatabase-cache - unknown status
  • tst_qmimedatabase-xml - unknown status
  • tst_qnetworkdiskcache - unknown status
  • tst_qnetworkproxyfactory - unknown status
  • tst_qobject - unknown status
  • ...
FALSEevaluated 4780 times by 440 tests
Evaluated by:
  • tst_QApplication
  • tst_QCommandLineParser
  • tst_QCoreApplication
  • tst_QDBusConnectionNoBus
  • tst_QDBusConnectionNoLibDBus1
  • tst_QDBusConnection_Delayed
  • tst_QDnsLookup_Appless
  • tst_QFuture
  • tst_QGlobal
  • tst_QGuiApplication
  • tst_QHostInfo
  • tst_QNetworkConfigurationManager
  • tst_QPointer
  • tst_QSql
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpSocket
  • tst_QTextCodec
  • tst_QThreadPool
  • tst_QtConcurrentRun
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • ...
957-4780
267 // move the contents of the set out so that we can iterate without the lock-
268 QSet<QThreadPoolThread *> allThreadsCopy;-
269 allThreadsCopy.swap(allThreads);-
270 locker.unlock();-
271-
272 foreachfor (QThreadPoolThread *thread ,: qAsConst(allThreadsCopy))) {-
273 thread->runnableReady.wakeAll();-
274 thread->wait();-
275 delete thread;-
276 }
executed 1182 times by 37 tests: end of block
Executed by:
  • tst_QDnsLookup_Appless
  • tst_QFuture
  • tst_QHostInfo
  • tst_QPointer
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpSocket
  • tst_QTextCodec
  • tst_QThreadPool
  • tst_QtConcurrentRun
  • tst_lancelot - unknown status
  • tst_qdebug - unknown status
  • tst_qdnslookup - unknown status
  • tst_qftp - unknown status
  • tst_qfuturewatcher - unknown status
  • tst_qhostinfo - unknown status
  • tst_qhttpnetworkconnection - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qlockfile - unknown status
  • tst_qmimedatabase-cache - unknown status
  • tst_qmimedatabase-xml - unknown status
  • tst_qnetworkdiskcache - unknown status
  • tst_qnetworkproxyfactory - unknown status
  • tst_qobject - unknown status
  • ...
1182
277-
278 locker.relock();-
279 // repeat until all newly arrived threads have also completed-
280 }
executed 957 times by 37 tests: end of block
Executed by:
  • tst_QDnsLookup_Appless
  • tst_QFuture
  • tst_QHostInfo
  • tst_QPointer
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpSocket
  • tst_QTextCodec
  • tst_QThreadPool
  • tst_QtConcurrentRun
  • tst_lancelot - unknown status
  • tst_qdebug - unknown status
  • tst_qdnslookup - unknown status
  • tst_qftp - unknown status
  • tst_qfuturewatcher - unknown status
  • tst_qhostinfo - unknown status
  • tst_qhttpnetworkconnection - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qlockfile - unknown status
  • tst_qmimedatabase-cache - unknown status
  • tst_qmimedatabase-xml - unknown status
  • tst_qnetworkdiskcache - unknown status
  • tst_qnetworkproxyfactory - unknown status
  • tst_qobject - unknown status
  • ...
957
281-
282 waitingThreads.clear();-
283 expiredThreads.clear();-
284-
285 isExiting = false;-
286}
executed 4780 times by 440 tests: end of block
Executed by:
  • tst_QApplication
  • tst_QCommandLineParser
  • tst_QCoreApplication
  • tst_QDBusConnectionNoBus
  • tst_QDBusConnectionNoLibDBus1
  • tst_QDBusConnection_Delayed
  • tst_QDnsLookup_Appless
  • tst_QFuture
  • tst_QGlobal
  • tst_QGuiApplication
  • tst_QHostInfo
  • tst_QNetworkConfigurationManager
  • tst_QPointer
  • tst_QSql
  • tst_QSslSocket
  • tst_QSslSocket_onDemandCertificates_member
  • tst_QSslSocket_onDemandCertificates_static
  • tst_QTcpSocket
  • tst_QTextCodec
  • tst_QThreadPool
  • tst_QtConcurrentRun
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • ...
4780
287-
288bool QThreadPoolPrivate::waitForDone(int msecs)-
289{-
290 QMutexLocker locker(&mutex);-
291 if (msecs < 0) {-
292 while (!(queue.isEmpty() && activeThreads == 0))-
293 noActiveThreads.wait(locker.mutex());-
294 } else {-
295 QElapsedTimer timer;-
296 timer.start();-
297 int t;-
298 while (!(queue.isEmpty() && activeThreads == 0) &&-
299 ((t = msecs - timer.elapsed()) > 0))-
300 noActiveThreads.wait(locker.mutex(), t);-
301 }-
302 return queue.isEmpty() && activeThreads == 0;-
303}-
304-
305void QThreadPoolPrivate::clear()-
306{-
307 QMutexLocker locker(&mutex);-
308 for (QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constBegin();-
309 it != queue.constEnd(); ++it) {-
310 QRunnable* r = it->first;-
311 if (r->autoDelete() && !--r->ref)-
312 delete r;-
313 }-
314 queue.clear();-
315}-
316-
317/*!-
318 \internal-
319 Searches for \a runnable in the queue, removes it from the queue and-
320 returns \c true if it was found in the queue-
321*/-
322bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable)-
323{-
324 if (runnable == 0)-
325 return false;-
326 {-
327 QMutexLocker locker(&mutex);-
328 QVector<QPair<QRunnable *, int> >::iterator it = queue.begin();-
329 QVector<QPair<QRunnable *, int> >::iterator end = queue.end();-
330-
331 while (it != end) {-
332 if (it->first == runnable) {-
333 queue.erase(it);-
334 return true;-
335 }-
336 ++it;-
337 }-
338 }-
339-
340 return false;-
341}-
342-
343 /*!-
344 \internal-
345 Searches for \a runnable in the queue, removes it from the queue and-
346 runs it if found. This function does not return until the runnable-
347 has completed.-
348 */-
349void QThreadPoolPrivate::stealAndRunRunnable(QRunnable *runnable)-
350{-
351 if (!stealRunnable(runnable))-
352 return;-
353 const bool autoDelete = runnable->autoDelete();-
354 bool del = autoDelete && !--runnable->ref;-
355-
356 runnable->run();-
357-
358 if (del) {-
359 delete runnable;-
360 }-
361}-
362-
363/*!-
364 \class QThreadPool-
365 \inmodule QtCore-
366 \brief The QThreadPool class manages a collection of QThreads.-
367 \since 4.4-
368 \threadsafe-
369-
370 \ingroup thread-
371-
372 QThreadPool manages and recyles individual QThread objects to help reduce-
373 thread creation costs in programs that use threads. Each Qt application-
374 has one global QThreadPool object, which can be accessed by calling-
375 globalInstance().-
376-
377 To use one of the QThreadPool threads, subclass QRunnable and implement-
378 the run() virtual function. Then create an object of that class and pass-
379 it to QThreadPool::start().-
380-
381 \snippet code/src_corelib_concurrent_qthreadpool.cpp 0-
382-
383 QThreadPool deletes the QRunnable automatically by default. Use-
384 QRunnable::setAutoDelete() to change the auto-deletion flag.-
385-
386 QThreadPool supports executing the same QRunnable more than once-
387 by calling tryStart(this) from within QRunnable::run().-
388 If autoDelete is enabled the QRunnable will be deleted when-
389 the last thread exits the run function. Calling start()-
390 multiple times with the same QRunnable when autoDelete is enabled-
391 creates a race condition and is not recommended.-
392-
393 Threads that are unused for a certain amount of time will expire. The-
394 default expiry timeout is 30000 milliseconds (30 seconds). This can be-
395 changed using setExpiryTimeout(). Setting a negative expiry timeout-
396 disables the expiry mechanism.-
397-
398 Call maxThreadCount() to query the maximum number of threads to be used.-
399 If needed, you can change the limit with setMaxThreadCount(). The default-
400 maxThreadCount() is QThread::idealThreadCount(). The activeThreadCount()-
401 function returns the number of threads currently doing work.-
402-
403 The reserveThread() function reserves a thread for external-
404 use. Use releaseThread() when your are done with the thread, so-
405 that it may be reused. Essentially, these functions temporarily-
406 increase or reduce the active thread count and are useful when-
407 implementing time-consuming operations that are not visible to the-
408 QThreadPool.-
409-
410 Note that QThreadPool is a low-level class for managing threads, see-
411 the Qt Concurrent module for higher level alternatives.-
412-
413 \sa QRunnable-
414*/-
415-
416/*!-
417 Constructs a thread pool with the given \a parent.-
418*/-
419QThreadPool::QThreadPool(QObject *parent)-
420 : QObject(*new QThreadPoolPrivate, parent)-
421{ }-
422-
423/*!-
424 Destroys the QThreadPool.-
425 This function will block until all runnables have been completed.-
426*/-
427QThreadPool::~QThreadPool()-
428{-
429 waitForDone();-
430}-
431-
432/*!-
433 Returns the global QThreadPool instance.-
434*/-
435QThreadPool *QThreadPool::globalInstance()-
436{-
437 return theInstance();-
438}-
439-
440/*!-
441 Reserves a thread and uses it to run \a runnable, unless this thread will-
442 make the current thread count exceed maxThreadCount(). In that case,-
443 \a runnable is added to a run queue instead. The \a priority argument can-
444 be used to control the run queue's order of execution.-
445-
446 Note that the thread pool takes ownership of the \a runnable if-
447 \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns \c true,-
448 and the \a runnable will be deleted automatically by the thread-
449 pool after the \l{QRunnable::run()}{runnable->run()} returns. If-
450 \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns \c false,-
451 ownership of \a runnable remains with the caller. Note that-
452 changing the auto-deletion on \a runnable after calling this-
453 functions results in undefined behavior.-
454*/-
455void QThreadPool::start(QRunnable *runnable, int priority)-
456{-
457 if (!runnable)-
458 return;-
459-
460 Q_D(QThreadPool);-
461 QMutexLocker locker(&d->mutex);-
462 if (!d->tryStart(runnable)) {-
463 d->enqueueTask(runnable, priority);-
464-
465 if (!d->waitingThreads.isEmpty())-
466 d->waitingThreads.takeFirst()->runnableReady.wakeOne();-
467 }-
468}-
469-
470/*!-
471 Attempts to reserve a thread to run \a runnable.-
472-
473 If no threads are available at the time of calling, then this function-
474 does nothing and returns \c false. Otherwise, \a runnable is run immediately-
475 using one available thread and this function returns \c true.-
476-
477 Note that the thread pool takes ownership of the \a runnable if-
478 \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns \c true,-
479 and the \a runnable will be deleted automatically by the thread-
480 pool after the \l{QRunnable::run()}{runnable->run()} returns. If-
481 \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns \c false,-
482 ownership of \a runnable remains with the caller. Note that-
483 changing the auto-deletion on \a runnable after calling this-
484 function results in undefined behavior.-
485*/-
486bool QThreadPool::tryStart(QRunnable *runnable)-
487{-
488 if (!runnable)-
489 return false;-
490-
491 Q_D(QThreadPool);-
492-
493 QMutexLocker locker(&d->mutex);-
494-
495 if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount)-
496 return false;-
497-
498 return d->tryStart(runnable);-
499}-
500-
501/*! \property QThreadPool::expiryTimeout-
502-
503 Threads that are unused for \a expiryTimeout milliseconds are considered-
504 to have expired and will exit. Such threads will be restarted as needed.-
505 The default \a expiryTimeout is 30000 milliseconds (30 seconds). If-
506 \a expiryTimeout is negative, newly created threads will not expire, e.g.,-
507 they will not exit until the thread pool is destroyed.-
508-
509 Note that setting \a expiryTimeout has no effect on already running-
510 threads. Only newly created threads will use the new \a expiryTimeout.-
511 We recommend setting the \a expiryTimeout immediately after creating the-
512 thread pool, but before calling start().-
513*/-
514-
515int QThreadPool::expiryTimeout() const-
516{-
517 Q_D(const QThreadPool);-
518 return d->expiryTimeout;-
519}-
520-
521void QThreadPool::setExpiryTimeout(int expiryTimeout)-
522{-
523 Q_D(QThreadPool);-
524 if (d->expiryTimeout == expiryTimeout)-
525 return;-
526 d->expiryTimeout = expiryTimeout;-
527}-
528-
529/*! \property QThreadPool::maxThreadCount-
530-
531 This property represents the maximum number of threads used by the thread-
532 pool.-
533-
534 \note The thread pool will always use at least 1 thread, even if-
535 \a maxThreadCount limit is zero or negative.-
536-
537 The default \a maxThreadCount is QThread::idealThreadCount().-
538*/-
539-
540int QThreadPool::maxThreadCount() const-
541{-
542 Q_D(const QThreadPool);-
543 return d->maxThreadCount;-
544}-
545-
546void QThreadPool::setMaxThreadCount(int maxThreadCount)-
547{-
548 Q_D(QThreadPool);-
549 QMutexLocker locker(&d->mutex);-
550-
551 if (maxThreadCount == d->maxThreadCount)-
552 return;-
553-
554 d->maxThreadCount = maxThreadCount;-
555 d->tryToStartMoreThreads();-
556}-
557-
558/*! \property QThreadPool::activeThreadCount-
559-
560 This property represents the number of active threads in the thread pool.-
561-
562 \note It is possible for this function to return a value that is greater-
563 than maxThreadCount(). See reserveThread() for more details.-
564-
565 \sa reserveThread(), releaseThread()-
566*/-
567-
568int QThreadPool::activeThreadCount() const-
569{-
570 Q_D(const QThreadPool);-
571 QMutexLocker locker(&d->mutex);-
572 return d->activeThreadCount();-
573}-
574-
575/*!-
576 Reserves one thread, disregarding activeThreadCount() and maxThreadCount().-
577-
578 Once you are done with the thread, call releaseThread() to allow it to be-
579 reused.-
580-
581 \note This function will always increase the number of active threads.-
582 This means that by using this function, it is possible for-
583 activeThreadCount() to return a value greater than maxThreadCount() .-
584-
585 \sa releaseThread()-
586 */-
587void QThreadPool::reserveThread()-
588{-
589 Q_D(QThreadPool);-
590 QMutexLocker locker(&d->mutex);-
591 ++d->reservedThreads;-
592}-
593-
594/*!-
595 Releases a thread previously reserved by a call to reserveThread().-
596-
597 \note Calling this function without previously reserving a thread-
598 temporarily increases maxThreadCount(). This is useful when a-
599 thread goes to sleep waiting for more work, allowing other threads-
600 to continue. Be sure to call reserveThread() when done waiting, so-
601 that the thread pool can correctly maintain the-
602 activeThreadCount().-
603-
604 \sa reserveThread()-
605*/-
606void QThreadPool::releaseThread()-
607{-
608 Q_D(QThreadPool);-
609 QMutexLocker locker(&d->mutex);-
610 --d->reservedThreads;-
611 d->tryToStartMoreThreads();-
612}-
613-
614/*!-
615 Waits up to \a msecs milliseconds for all threads to exit and removes all-
616 threads from the thread pool. Returns \c true if all threads were removed;-
617 otherwise it returns \c false. If \a msecs is -1 (the default), the timeout-
618 is ignored (waits for the last thread to exit).-
619*/-
620bool QThreadPool::waitForDone(int msecs)-
621{-
622 Q_D(QThreadPool);-
623 bool rc = d->waitForDone(msecs);-
624 if (rc)-
625 d->reset();-
626 return rc;-
627}-
628-
629/*!-
630 \since 5.2-
631-
632 Removes the runnables that are not yet started from the queue.-
633 The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()}-
634 returns \c true are deleted.-
635-
636 \sa start()-
637*/-
638void QThreadPool::clear()-
639{-
640 Q_D(QThreadPool);-
641 d->clear();-
642}-
643-
644/*!-
645 \since 5.5-
646-
647 Removes the specified \a runnable from the queue if it is not yet started.-
648 The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()}-
649 returns \c true are deleted.-
650-
651 \sa start()-
652*/-
653void QThreadPool::cancel(QRunnable *runnable)-
654{-
655 Q_D(QThreadPool);-
656 if (!d->stealRunnable(runnable))-
657 return;-
658 if (runnable->autoDelete() && !--runnable->ref) {-
659 delete runnable;-
660 }-
661}-
662-
663QT_END_NAMESPACE-
664-
665#endif-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9