| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qthread.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /**************************************************************************** | - | ||||||||||||||||||
| 2 | ** | - | ||||||||||||||||||
| 3 | ** Copyright (C) 2015 The Qt Company Ltd. | - | ||||||||||||||||||
| 4 | ** Contact: http://www.qt.io/licensing/ | - | ||||||||||||||||||
| 5 | ** | - | ||||||||||||||||||
| 6 | ** This file is part of the QtCore module of the Qt Toolkit. | - | ||||||||||||||||||
| 7 | ** | - | ||||||||||||||||||
| 8 | ** $QT_BEGIN_LICENSE:LGPL21$ | - | ||||||||||||||||||
| 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 http://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
| 15 | ** information use the contact form at http://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 2.1 or version 3 as published by the Free | - | ||||||||||||||||||
| 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | - | ||||||||||||||||||
| 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the | - | ||||||||||||||||||
| 22 | ** following information to ensure the GNU Lesser General Public License | - | ||||||||||||||||||
| 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and | - | ||||||||||||||||||
| 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - | ||||||||||||||||||
| 25 | ** | - | ||||||||||||||||||
| 26 | ** As a special exception, The Qt Company gives you certain additional | - | ||||||||||||||||||
| 27 | ** rights. These rights are described in The Qt Company LGPL Exception | - | ||||||||||||||||||
| 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - | ||||||||||||||||||
| 29 | ** | - | ||||||||||||||||||
| 30 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
| 31 | ** | - | ||||||||||||||||||
| 32 | ****************************************************************************/ | - | ||||||||||||||||||
| 33 | - | |||||||||||||||||||
| 34 | #include "qthread.h" | - | ||||||||||||||||||
| 35 | #include "qthreadstorage.h" | - | ||||||||||||||||||
| 36 | #include "qmutex.h" | - | ||||||||||||||||||
| 37 | #include "qreadwritelock.h" | - | ||||||||||||||||||
| 38 | #include "qabstracteventdispatcher.h" | - | ||||||||||||||||||
| 39 | - | |||||||||||||||||||
| 40 | #include <qeventloop.h> | - | ||||||||||||||||||
| 41 | - | |||||||||||||||||||
| 42 | #include "qthread_p.h" | - | ||||||||||||||||||
| 43 | #include "private/qcoreapplication_p.h" | - | ||||||||||||||||||
| 44 | - | |||||||||||||||||||
| 45 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
| 46 | - | |||||||||||||||||||
| 47 | /* | - | ||||||||||||||||||
| 48 | QThreadData | - | ||||||||||||||||||
| 49 | */ | - | ||||||||||||||||||
| 50 | - | |||||||||||||||||||
| 51 | QThreadData::QThreadData(int initialRefCount) | - | ||||||||||||||||||
| 52 | : _ref(initialRefCount), loopLevel(0), thread(0), threadId(0), | - | ||||||||||||||||||
| 53 | eventDispatcher(0), | - | ||||||||||||||||||
| 54 | quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true) | - | ||||||||||||||||||
| 55 | { | - | ||||||||||||||||||
| 56 | // fprintf(stderr, "QThreadData %p created\n", this); | - | ||||||||||||||||||
| 57 | } executed 603179 times by 713 tests: end of blockExecuted by:
| 603179 | ||||||||||||||||||
| 58 | - | |||||||||||||||||||
| 59 | QThreadData::~QThreadData() | - | ||||||||||||||||||
| 60 | { | - | ||||||||||||||||||
| 61 | Q_ASSERT(_ref.load() == 0); | - | ||||||||||||||||||
| 62 | - | |||||||||||||||||||
| 63 | // In the odd case that Qt is running on a secondary thread, the main | - | ||||||||||||||||||
| 64 | // thread instance will have been dereffed asunder because of the deref in | - | ||||||||||||||||||
| 65 | // QThreadData::current() and the deref in the pthread_destroy. To avoid | - | ||||||||||||||||||
| 66 | // crashing during QCoreApplicationData's global static cleanup we need to | - | ||||||||||||||||||
| 67 | // safeguard the main thread here.. This fix is a bit crude, but it solves | - | ||||||||||||||||||
| 68 | // the problem... | - | ||||||||||||||||||
| 69 | if (this->thread == QCoreApplicationPrivate::theMainThread) {
| 893-601705 | ||||||||||||||||||
| 70 | QCoreApplicationPrivate::theMainThread = 0; | - | ||||||||||||||||||
| 71 | QThreadData::clearCurrentThreadData(); | - | ||||||||||||||||||
| 72 | } executed 893 times by 347 tests: end of blockExecuted by:
| 893 | ||||||||||||||||||
| 73 | - | |||||||||||||||||||
| 74 | QThread *t = thread; | - | ||||||||||||||||||
| 75 | thread = 0; | - | ||||||||||||||||||
| 76 | delete t; | - | ||||||||||||||||||
| 77 | - | |||||||||||||||||||
| 78 | for (int i = 0; i < postEventList.size(); ++i) {
| 1456-602598 | ||||||||||||||||||
| 79 | const QPostEvent &pe = postEventList.at(i); | - | ||||||||||||||||||
| 80 | if (pe.event) {
| 0-1456 | ||||||||||||||||||
| 81 | --pe.receiver->d_func()->postedEvents; | - | ||||||||||||||||||
| 82 | pe.event->posted = false; | - | ||||||||||||||||||
| 83 | delete pe.event; | - | ||||||||||||||||||
| 84 | } never executed: end of block | 0 | ||||||||||||||||||
| 85 | } executed 1456 times by 50 tests: end of blockExecuted by:
| 1456 | ||||||||||||||||||
| 86 | - | |||||||||||||||||||
| 87 | // fprintf(stderr, "QThreadData %p destroyed\n", this); | - | ||||||||||||||||||
| 88 | } executed 602598 times by 580 tests: end of blockExecuted by:
| 602598 | ||||||||||||||||||
| 89 | - | |||||||||||||||||||
| 90 | void QThreadData::ref() | - | ||||||||||||||||||
| 91 | { | - | ||||||||||||||||||
| 92 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
| 93 | (void) _ref.ref(); | - | ||||||||||||||||||
| 94 | Q_ASSERT(_ref.load() != 0); | - | ||||||||||||||||||
| 95 | #endif | - | ||||||||||||||||||
| 96 | } executed 2710482 times by 946 tests: end of blockExecuted by:
| 2710482 | ||||||||||||||||||
| 97 | - | |||||||||||||||||||
| 98 | void QThreadData::deref() | - | ||||||||||||||||||
| 99 | { | - | ||||||||||||||||||
| 100 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
| 101 | if (!_ref.deref())
| 602598-2708661 | ||||||||||||||||||
| 102 | delete this; executed 602598 times by 580 tests: delete this;Executed by:
| 602598 | ||||||||||||||||||
| 103 | #endif | - | ||||||||||||||||||
| 104 | } executed 3311181 times by 929 tests: end of blockExecuted by:
| 3311181 | ||||||||||||||||||
| 105 | - | |||||||||||||||||||
| 106 | /* | - | ||||||||||||||||||
| 107 | QAdoptedThread | - | ||||||||||||||||||
| 108 | */ | - | ||||||||||||||||||
| 109 | - | |||||||||||||||||||
| 110 | QAdoptedThread::QAdoptedThread(QThreadData *data) | - | ||||||||||||||||||
| 111 | : QThread(*new QThreadPrivate(data)) | - | ||||||||||||||||||
| 112 | { | - | ||||||||||||||||||
| 113 | // thread should be running and not finished for the lifetime | - | ||||||||||||||||||
| 114 | // of the application (even if QCoreApplication goes away) | - | ||||||||||||||||||
| 115 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
| 116 | d_func()->running = true; | - | ||||||||||||||||||
| 117 | d_func()->finished = false; | - | ||||||||||||||||||
| 118 | init(); | - | ||||||||||||||||||
| 119 | #endif | - | ||||||||||||||||||
| 120 | - | |||||||||||||||||||
| 121 | // fprintf(stderr, "new QAdoptedThread = %p\n", this); | - | ||||||||||||||||||
| 122 | } executed 1008 times by 19 tests: end of blockExecuted by:
| 1008 | ||||||||||||||||||
| 123 | - | |||||||||||||||||||
| 124 | QAdoptedThread::~QAdoptedThread() | - | ||||||||||||||||||
| 125 | { | - | ||||||||||||||||||
| 126 | // fprintf(stderr, "~QAdoptedThread = %p\n", this); | - | ||||||||||||||||||
| 127 | } | - | ||||||||||||||||||
| 128 | - | |||||||||||||||||||
| 129 | void QAdoptedThread::run() | - | ||||||||||||||||||
| 130 | { | - | ||||||||||||||||||
| 131 | // this function should never be called | - | ||||||||||||||||||
| 132 | qFatal("QAdoptedThread::run(): Internal error, this implementation should never be called."); | - | ||||||||||||||||||
| 133 | } never executed: end of block | 0 | ||||||||||||||||||
| 134 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
| 135 | /* | - | ||||||||||||||||||
| 136 | QThreadPrivate | - | ||||||||||||||||||
| 137 | */ | - | ||||||||||||||||||
| 138 | - | |||||||||||||||||||
| 139 | QThreadPrivate::QThreadPrivate(QThreadData *d) | - | ||||||||||||||||||
| 140 | : QObjectPrivate(), running(false), finished(false), | - | ||||||||||||||||||
| 141 | isInFinish(false), interruptionRequested(false), | - | ||||||||||||||||||
| 142 | exited(false), returnCode(-1), | - | ||||||||||||||||||
| 143 | stackSize(0), priority(QThread::InheritPriority), data(d) | - | ||||||||||||||||||
| 144 | { | - | ||||||||||||||||||
| 145 | #if defined (Q_OS_WIN) | - | ||||||||||||||||||
| 146 | handle = 0; | - | ||||||||||||||||||
| 147 | # ifndef Q_OS_WINRT | - | ||||||||||||||||||
| 148 | id = 0; | - | ||||||||||||||||||
| 149 | # endif | - | ||||||||||||||||||
| 150 | waiters = 0; | - | ||||||||||||||||||
| 151 | terminationEnabled = true; | - | ||||||||||||||||||
| 152 | terminatePending = false; | - | ||||||||||||||||||
| 153 | #endif | - | ||||||||||||||||||
| 154 | - | |||||||||||||||||||
| 155 | if (!data)
| 1008-601945 | ||||||||||||||||||
| 156 | data = new QThreadData; executed 601945 times by 545 tests: data = new QThreadData;Executed by:
| 601945 | ||||||||||||||||||
| 157 | } executed 602953 times by 556 tests: end of blockExecuted by:
| 602953 | ||||||||||||||||||
| 158 | - | |||||||||||||||||||
| 159 | QThreadPrivate::~QThreadPrivate() | - | ||||||||||||||||||
| 160 | { | - | ||||||||||||||||||
| 161 | data->deref(); | - | ||||||||||||||||||
| 162 | } executed 603002 times by 609 tests: end of blockExecuted by:
| 603002 | ||||||||||||||||||
| 163 | - | |||||||||||||||||||
| 164 | /*! | - | ||||||||||||||||||
| 165 | \class QThread | - | ||||||||||||||||||
| 166 | \inmodule QtCore | - | ||||||||||||||||||
| 167 | \brief The QThread class provides a platform-independent way to | - | ||||||||||||||||||
| 168 | manage threads. | - | ||||||||||||||||||
| 169 | - | |||||||||||||||||||
| 170 | \ingroup thread | - | ||||||||||||||||||
| 171 | - | |||||||||||||||||||
| 172 | A QThread object manages one thread of control within the | - | ||||||||||||||||||
| 173 | program. QThreads begin executing in run(). By default, run() starts the | - | ||||||||||||||||||
| 174 | event loop by calling exec() and runs a Qt event loop inside the thread. | - | ||||||||||||||||||
| 175 | - | |||||||||||||||||||
| 176 | You can use worker objects by moving them to the thread using | - | ||||||||||||||||||
| 177 | QObject::moveToThread(). | - | ||||||||||||||||||
| 178 | - | |||||||||||||||||||
| 179 | \snippet code/src_corelib_thread_qthread.cpp worker | - | ||||||||||||||||||
| 180 | - | |||||||||||||||||||
| 181 | The code inside the Worker's slot would then execute in a | - | ||||||||||||||||||
| 182 | separate thread. However, you are free to connect the | - | ||||||||||||||||||
| 183 | Worker's slots to any signal, from any object, in any thread. It | - | ||||||||||||||||||
| 184 | is safe to connect signals and slots across different threads, | - | ||||||||||||||||||
| 185 | thanks to a mechanism called \l{Qt::QueuedConnection}{queued | - | ||||||||||||||||||
| 186 | connections}. | - | ||||||||||||||||||
| 187 | - | |||||||||||||||||||
| 188 | Another way to make code run in a separate thread, is to subclass QThread | - | ||||||||||||||||||
| 189 | and reimplement run(). For example: | - | ||||||||||||||||||
| 190 | - | |||||||||||||||||||
| 191 | \snippet code/src_corelib_thread_qthread.cpp reimpl-run | - | ||||||||||||||||||
| 192 | - | |||||||||||||||||||
| 193 | In that example, the thread will exit after the run function has returned. | - | ||||||||||||||||||
| 194 | There will not be any event loop running in the thread unless you call | - | ||||||||||||||||||
| 195 | exec(). | - | ||||||||||||||||||
| 196 | - | |||||||||||||||||||
| 197 | It is important to remember that a QThread instance \l{QObject#Thread | - | ||||||||||||||||||
| 198 | Affinity}{lives in} the old thread that instantiated it, not in the | - | ||||||||||||||||||
| 199 | new thread that calls run(). This means that all of QThread's queued | - | ||||||||||||||||||
| 200 | slots will execute in the old thread. Thus, a developer who wishes to | - | ||||||||||||||||||
| 201 | invoke slots in the new thread must use the worker-object approach; new | - | ||||||||||||||||||
| 202 | slots should not be implemented directly into a subclassed QThread. | - | ||||||||||||||||||
| 203 | - | |||||||||||||||||||
| 204 | When subclassing QThread, keep in mind that the constructor executes in | - | ||||||||||||||||||
| 205 | the old thread while run() executes in the new thread. If a member | - | ||||||||||||||||||
| 206 | variable is accessed from both functions, then the variable is accessed | - | ||||||||||||||||||
| 207 | from two different threads. Check that it is safe to do so. | - | ||||||||||||||||||
| 208 | - | |||||||||||||||||||
| 209 | \note Care must be taken when interacting with objects across different | - | ||||||||||||||||||
| 210 | threads. See \l{Synchronizing Threads} for details. | - | ||||||||||||||||||
| 211 | - | |||||||||||||||||||
| 212 | \section1 Managing Threads | - | ||||||||||||||||||
| 213 | - | |||||||||||||||||||
| 214 | QThread will notifiy you via a signal when the thread is | - | ||||||||||||||||||
| 215 | started() and finished(), or you can use isFinished() and | - | ||||||||||||||||||
| 216 | isRunning() to query the state of the thread. | - | ||||||||||||||||||
| 217 | - | |||||||||||||||||||
| 218 | You can stop the thread by calling exit() or quit(). In extreme | - | ||||||||||||||||||
| 219 | cases, you may want to forcibly terminate() an executing thread. | - | ||||||||||||||||||
| 220 | However, doing so is dangerous and discouraged. Please read the | - | ||||||||||||||||||
| 221 | documentation for terminate() and setTerminationEnabled() for | - | ||||||||||||||||||
| 222 | detailed information. | - | ||||||||||||||||||
| 223 | - | |||||||||||||||||||
| 224 | From Qt 4.8 onwards, it is possible to deallocate objects that | - | ||||||||||||||||||
| 225 | live in a thread that has just ended, by connecting the | - | ||||||||||||||||||
| 226 | finished() signal to QObject::deleteLater(). | - | ||||||||||||||||||
| 227 | - | |||||||||||||||||||
| 228 | Use wait() to block the calling thread, until the other thread | - | ||||||||||||||||||
| 229 | has finished execution (or until a specified time has passed). | - | ||||||||||||||||||
| 230 | - | |||||||||||||||||||
| 231 | QThread also provides static, platform independent sleep | - | ||||||||||||||||||
| 232 | functions: sleep(), msleep(), and usleep() allow full second, | - | ||||||||||||||||||
| 233 | millisecond, and microsecond resolution respectively. These | - | ||||||||||||||||||
| 234 | functions were made public in Qt 5.0. | - | ||||||||||||||||||
| 235 | - | |||||||||||||||||||
| 236 | \note wait() and the sleep() functions should be unnecessary in | - | ||||||||||||||||||
| 237 | general, since Qt is an event-driven framework. Instead of | - | ||||||||||||||||||
| 238 | wait(), consider listening for the finished() signal. Instead of | - | ||||||||||||||||||
| 239 | the sleep() functions, consider using QTimer. | - | ||||||||||||||||||
| 240 | - | |||||||||||||||||||
| 241 | The static functions currentThreadId() and currentThread() return | - | ||||||||||||||||||
| 242 | identifiers for the currently executing thread. The former | - | ||||||||||||||||||
| 243 | returns a platform specific ID for the thread; the latter returns | - | ||||||||||||||||||
| 244 | a QThread pointer. | - | ||||||||||||||||||
| 245 | - | |||||||||||||||||||
| 246 | To choose the name that your thread will be given (as identified | - | ||||||||||||||||||
| 247 | by the command \c{ps -L} on Linux, for example), you can call | - | ||||||||||||||||||
| 248 | \l{QObject::setObjectName()}{setObjectName()} before starting the thread. | - | ||||||||||||||||||
| 249 | If you don't call \l{QObject::setObjectName()}{setObjectName()}, | - | ||||||||||||||||||
| 250 | the name given to your thread will be the class name of the runtime | - | ||||||||||||||||||
| 251 | type of your thread object (for example, \c "RenderThread" in the case of the | - | ||||||||||||||||||
| 252 | \l{Mandelbrot Example}, as that is the name of the QThread subclass). | - | ||||||||||||||||||
| 253 | Note that this is currently not available with release builds on Windows. | - | ||||||||||||||||||
| 254 | - | |||||||||||||||||||
| 255 | \sa {Thread Support in Qt}, QThreadStorage, {Synchronizing Threads}, | - | ||||||||||||||||||
| 256 | {Mandelbrot Example}, {Semaphores Example}, {Wait Conditions Example} | - | ||||||||||||||||||
| 257 | */ | - | ||||||||||||||||||
| 258 | - | |||||||||||||||||||
| 259 | /*! | - | ||||||||||||||||||
| 260 | \fn Qt::HANDLE QThread::currentThreadId() | - | ||||||||||||||||||
| 261 | - | |||||||||||||||||||
| 262 | Returns the thread handle of the currently executing thread. | - | ||||||||||||||||||
| 263 | - | |||||||||||||||||||
| 264 | \warning The handle returned by this function is used for internal | - | ||||||||||||||||||
| 265 | purposes and should not be used in any application code. | - | ||||||||||||||||||
| 266 | - | |||||||||||||||||||
| 267 | \warning On Windows, the returned value is a pseudo-handle for the | - | ||||||||||||||||||
| 268 | current thread. It can't be used for numerical comparison. i.e., | - | ||||||||||||||||||
| 269 | this function returns the DWORD (Windows-Thread ID) returned by | - | ||||||||||||||||||
| 270 | the Win32 function getCurrentThreadId(), not the HANDLE | - | ||||||||||||||||||
| 271 | (Windows-Thread HANDLE) returned by the Win32 function | - | ||||||||||||||||||
| 272 | getCurrentThread(). | - | ||||||||||||||||||
| 273 | */ | - | ||||||||||||||||||
| 274 | - | |||||||||||||||||||
| 275 | /*! | - | ||||||||||||||||||
| 276 | \fn int QThread::idealThreadCount() | - | ||||||||||||||||||
| 277 | - | |||||||||||||||||||
| 278 | Returns the ideal number of threads that can be run on the system. This is done querying | - | ||||||||||||||||||
| 279 | the number of processor cores, both real and logical, in the system. This function returns -1 | - | ||||||||||||||||||
| 280 | if the number of processor cores could not be detected. | - | ||||||||||||||||||
| 281 | */ | - | ||||||||||||||||||
| 282 | - | |||||||||||||||||||
| 283 | /*! | - | ||||||||||||||||||
| 284 | \fn void QThread::yieldCurrentThread() | - | ||||||||||||||||||
| 285 | - | |||||||||||||||||||
| 286 | Yields execution of the current thread to another runnable thread, | - | ||||||||||||||||||
| 287 | if any. Note that the operating system decides to which thread to | - | ||||||||||||||||||
| 288 | switch. | - | ||||||||||||||||||
| 289 | */ | - | ||||||||||||||||||
| 290 | - | |||||||||||||||||||
| 291 | /*! | - | ||||||||||||||||||
| 292 | \fn void QThread::start(Priority priority) | - | ||||||||||||||||||
| 293 | - | |||||||||||||||||||
| 294 | Begins execution of the thread by calling run(). The | - | ||||||||||||||||||
| 295 | operating system will schedule the thread according to the \a | - | ||||||||||||||||||
| 296 | priority parameter. If the thread is already running, this | - | ||||||||||||||||||
| 297 | function does nothing. | - | ||||||||||||||||||
| 298 | - | |||||||||||||||||||
| 299 | The effect of the \a priority parameter is dependent on the | - | ||||||||||||||||||
| 300 | operating system's scheduling policy. In particular, the \a priority | - | ||||||||||||||||||
| 301 | will be ignored on systems that do not support thread priorities | - | ||||||||||||||||||
| 302 | (such as on Linux, see the | - | ||||||||||||||||||
| 303 | \l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler} | - | ||||||||||||||||||
| 304 | documentation for more details). | - | ||||||||||||||||||
| 305 | - | |||||||||||||||||||
| 306 | \sa run(), terminate() | - | ||||||||||||||||||
| 307 | */ | - | ||||||||||||||||||
| 308 | - | |||||||||||||||||||
| 309 | /*! | - | ||||||||||||||||||
| 310 | \fn void QThread::started() | - | ||||||||||||||||||
| 311 | - | |||||||||||||||||||
| 312 | This signal is emitted from the associated thread when it starts executing, | - | ||||||||||||||||||
| 313 | before the run() function is called. | - | ||||||||||||||||||
| 314 | - | |||||||||||||||||||
| 315 | \sa finished() | - | ||||||||||||||||||
| 316 | */ | - | ||||||||||||||||||
| 317 | - | |||||||||||||||||||
| 318 | /*! | - | ||||||||||||||||||
| 319 | \fn void QThread::finished() | - | ||||||||||||||||||
| 320 | - | |||||||||||||||||||
| 321 | This signal is emitted from the associated thread right before it finishes executing. | - | ||||||||||||||||||
| 322 | - | |||||||||||||||||||
| 323 | When this signal is emitted, the event loop has already stopped running. | - | ||||||||||||||||||
| 324 | No more events will be processed in the thread, except for deferred deletion events. | - | ||||||||||||||||||
| 325 | This signal can be connected to QObject::deleteLater(), to free objects in that thread. | - | ||||||||||||||||||
| 326 | - | |||||||||||||||||||
| 327 | \note If the associated thread was terminated using terminate(), it is undefined from | - | ||||||||||||||||||
| 328 | which thread this signal is emitted. | - | ||||||||||||||||||
| 329 | - | |||||||||||||||||||
| 330 | \sa started() | - | ||||||||||||||||||
| 331 | */ | - | ||||||||||||||||||
| 332 | - | |||||||||||||||||||
| 333 | /*! | - | ||||||||||||||||||
| 334 | \enum QThread::Priority | - | ||||||||||||||||||
| 335 | - | |||||||||||||||||||
| 336 | This enum type indicates how the operating system should schedule | - | ||||||||||||||||||
| 337 | newly created threads. | - | ||||||||||||||||||
| 338 | - | |||||||||||||||||||
| 339 | \value IdlePriority scheduled only when no other threads are | - | ||||||||||||||||||
| 340 | running. | - | ||||||||||||||||||
| 341 | - | |||||||||||||||||||
| 342 | \value LowestPriority scheduled less often than LowPriority. | - | ||||||||||||||||||
| 343 | \value LowPriority scheduled less often than NormalPriority. | - | ||||||||||||||||||
| 344 | - | |||||||||||||||||||
| 345 | \value NormalPriority the default priority of the operating | - | ||||||||||||||||||
| 346 | system. | - | ||||||||||||||||||
| 347 | - | |||||||||||||||||||
| 348 | \value HighPriority scheduled more often than NormalPriority. | - | ||||||||||||||||||
| 349 | \value HighestPriority scheduled more often than HighPriority. | - | ||||||||||||||||||
| 350 | - | |||||||||||||||||||
| 351 | \value TimeCriticalPriority scheduled as often as possible. | - | ||||||||||||||||||
| 352 | - | |||||||||||||||||||
| 353 | \value InheritPriority use the same priority as the creating | - | ||||||||||||||||||
| 354 | thread. This is the default. | - | ||||||||||||||||||
| 355 | */ | - | ||||||||||||||||||
| 356 | - | |||||||||||||||||||
| 357 | /*! | - | ||||||||||||||||||
| 358 | Returns a pointer to a QThread which manages the currently | - | ||||||||||||||||||
| 359 | executing thread. | - | ||||||||||||||||||
| 360 | */ | - | ||||||||||||||||||
| 361 | QThread *QThread::currentThread() | - | ||||||||||||||||||
| 362 | { | - | ||||||||||||||||||
| 363 | QThreadData *data = QThreadData::current(); | - | ||||||||||||||||||
| 364 | Q_ASSERT(data != 0); | - | ||||||||||||||||||
| 365 | return data->thread; executed 5059558 times by 769 tests: return data->thread;Executed by:
| 5059558 | ||||||||||||||||||
| 366 | } | - | ||||||||||||||||||
| 367 | - | |||||||||||||||||||
| 368 | /*! | - | ||||||||||||||||||
| 369 | Constructs a new QThread to manage a new thread. The \a parent | - | ||||||||||||||||||
| 370 | takes ownership of the QThread. The thread does not begin | - | ||||||||||||||||||
| 371 | executing until start() is called. | - | ||||||||||||||||||
| 372 | - | |||||||||||||||||||
| 373 | \sa start() | - | ||||||||||||||||||
| 374 | */ | - | ||||||||||||||||||
| 375 | QThread::QThread(QObject *parent) | - | ||||||||||||||||||
| 376 | : QObject(*(new QThreadPrivate), parent) | - | ||||||||||||||||||
| 377 | { | - | ||||||||||||||||||
| 378 | Q_D(QThread); | - | ||||||||||||||||||
| 379 | // fprintf(stderr, "QThreadData %p created for thread %p\n", d->data, this); | - | ||||||||||||||||||
| 380 | d->data->thread = this; | - | ||||||||||||||||||
| 381 | } executed 601945 times by 545 tests: end of blockExecuted by:
| 601945 | ||||||||||||||||||
| 382 | - | |||||||||||||||||||
| 383 | /*! | - | ||||||||||||||||||
| 384 | \internal | - | ||||||||||||||||||
| 385 | */ | - | ||||||||||||||||||
| 386 | QThread::QThread(QThreadPrivate &dd, QObject *parent) | - | ||||||||||||||||||
| 387 | : QObject(dd, parent) | - | ||||||||||||||||||
| 388 | { | - | ||||||||||||||||||
| 389 | Q_D(QThread); | - | ||||||||||||||||||
| 390 | // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); | - | ||||||||||||||||||
| 391 | d->data->thread = this; | - | ||||||||||||||||||
| 392 | } executed 1008 times by 19 tests: end of blockExecuted by:
| 1008 | ||||||||||||||||||
| 393 | - | |||||||||||||||||||
| 394 | /*! | - | ||||||||||||||||||
| 395 | Destroys the QThread. | - | ||||||||||||||||||
| 396 | - | |||||||||||||||||||
| 397 | Note that deleting a QThread object will not stop the execution | - | ||||||||||||||||||
| 398 | of the thread it manages. Deleting a running QThread (i.e. | - | ||||||||||||||||||
| 399 | isFinished() returns \c false) will probably result in a program | - | ||||||||||||||||||
| 400 | crash. Wait for the finished() signal before deleting the | - | ||||||||||||||||||
| 401 | QThread. | - | ||||||||||||||||||
| 402 | */ | - | ||||||||||||||||||
| 403 | QThread::~QThread() | - | ||||||||||||||||||
| 404 | { | - | ||||||||||||||||||
| 405 | Q_D(QThread); | - | ||||||||||||||||||
| 406 | { | - | ||||||||||||||||||
| 407 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 408 | if (d->isInFinish) {
| 57-602945 | ||||||||||||||||||
| 409 | locker.unlock(); | - | ||||||||||||||||||
| 410 | wait(); | - | ||||||||||||||||||
| 411 | locker.relock(); | - | ||||||||||||||||||
| 412 | } executed 57 times by 5 tests: end of blockExecuted by:
| 57 | ||||||||||||||||||
| 413 | if (d->running && !d->finished && !d->data->isAdopted)
| 0-602110 | ||||||||||||||||||
| 414 | qWarning("QThread: Destroyed while thread is still running"); never executed: QMessageLogger(__FILE__, 414, __PRETTY_FUNCTION__).warning("QThread: Destroyed while thread is still running"); | 0 | ||||||||||||||||||
| 415 | - | |||||||||||||||||||
| 416 | d->data->thread = 0; | - | ||||||||||||||||||
| 417 | } | - | ||||||||||||||||||
| 418 | } executed 603002 times by 609 tests: end of blockExecuted by:
| 603002 | ||||||||||||||||||
| 419 | - | |||||||||||||||||||
| 420 | /*! | - | ||||||||||||||||||
| 421 | Returns \c true if the thread is finished; otherwise returns \c false. | - | ||||||||||||||||||
| 422 | - | |||||||||||||||||||
| 423 | \sa isRunning() | - | ||||||||||||||||||
| 424 | */ | - | ||||||||||||||||||
| 425 | bool QThread::isFinished() const | - | ||||||||||||||||||
| 426 | { | - | ||||||||||||||||||
| 427 | Q_D(const QThread); | - | ||||||||||||||||||
| 428 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 429 | return d->finished || d->isInFinish; executed 429542 times by 14 tests: return d->finished || d->isInFinish;Executed by:
| 653-429542 | ||||||||||||||||||
| 430 | } | - | ||||||||||||||||||
| 431 | - | |||||||||||||||||||
| 432 | /*! | - | ||||||||||||||||||
| 433 | Returns \c true if the thread is running; otherwise returns \c false. | - | ||||||||||||||||||
| 434 | - | |||||||||||||||||||
| 435 | \sa isFinished() | - | ||||||||||||||||||
| 436 | */ | - | ||||||||||||||||||
| 437 | bool QThread::isRunning() const | - | ||||||||||||||||||
| 438 | { | - | ||||||||||||||||||
| 439 | Q_D(const QThread); | - | ||||||||||||||||||
| 440 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 441 | return d->running && !d->isInFinish; executed 683 times by 228 tests: return d->running && !d->isInFinish;Executed by:
| 45-683 | ||||||||||||||||||
| 442 | } | - | ||||||||||||||||||
| 443 | - | |||||||||||||||||||
| 444 | /*! | - | ||||||||||||||||||
| 445 | Sets the maximum stack size for the thread to \a stackSize. If \a | - | ||||||||||||||||||
| 446 | stackSize is greater than zero, the maximum stack size is set to | - | ||||||||||||||||||
| 447 | \a stackSize bytes, otherwise the maximum stack size is | - | ||||||||||||||||||
| 448 | automatically determined by the operating system. | - | ||||||||||||||||||
| 449 | - | |||||||||||||||||||
| 450 | \warning Most operating systems place minimum and maximum limits | - | ||||||||||||||||||
| 451 | on thread stack sizes. The thread will fail to start if the stack | - | ||||||||||||||||||
| 452 | size is outside these limits. | - | ||||||||||||||||||
| 453 | - | |||||||||||||||||||
| 454 | \sa stackSize() | - | ||||||||||||||||||
| 455 | */ | - | ||||||||||||||||||
| 456 | void QThread::setStackSize(uint stackSize) | - | ||||||||||||||||||
| 457 | { | - | ||||||||||||||||||
| 458 | Q_D(QThread); | - | ||||||||||||||||||
| 459 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 460 | Q_ASSERT_X(!d->running, "QThread::setStackSize", | - | ||||||||||||||||||
| 461 | "cannot change stack size while the thread is running"); | - | ||||||||||||||||||
| 462 | d->stackSize = stackSize; | - | ||||||||||||||||||
| 463 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 464 | - | |||||||||||||||||||
| 465 | /*! | - | ||||||||||||||||||
| 466 | Returns the maximum stack size for the thread (if set with | - | ||||||||||||||||||
| 467 | setStackSize()); otherwise returns zero. | - | ||||||||||||||||||
| 468 | - | |||||||||||||||||||
| 469 | \sa setStackSize() | - | ||||||||||||||||||
| 470 | */ | - | ||||||||||||||||||
| 471 | uint QThread::stackSize() const | - | ||||||||||||||||||
| 472 | { | - | ||||||||||||||||||
| 473 | Q_D(const QThread); | - | ||||||||||||||||||
| 474 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 475 | return d->stackSize; executed 3 times by 1 test: return d->stackSize;Executed by:
| 3 | ||||||||||||||||||
| 476 | } | - | ||||||||||||||||||
| 477 | - | |||||||||||||||||||
| 478 | /*! | - | ||||||||||||||||||
| 479 | Enters the event loop and waits until exit() is called, returning the value | - | ||||||||||||||||||
| 480 | that was passed to exit(). The value returned is 0 if exit() is called via | - | ||||||||||||||||||
| 481 | quit(). | - | ||||||||||||||||||
| 482 | - | |||||||||||||||||||
| 483 | This function is meant to be called from within run(). It is necessary to | - | ||||||||||||||||||
| 484 | call this function to start event handling. | - | ||||||||||||||||||
| 485 | - | |||||||||||||||||||
| 486 | \sa quit(), exit() | - | ||||||||||||||||||
| 487 | */ | - | ||||||||||||||||||
| 488 | int QThread::exec() | - | ||||||||||||||||||
| 489 | { | - | ||||||||||||||||||
| 490 | Q_D(QThread); | - | ||||||||||||||||||
| 491 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 492 | d->data->quitNow = false; | - | ||||||||||||||||||
| 493 | if (d->exited) {
| 28-937 | ||||||||||||||||||
| 494 | d->exited = false; | - | ||||||||||||||||||
| 495 | return d->returnCode; executed 28 times by 2 tests: return d->returnCode;Executed by:
| 28 | ||||||||||||||||||
| 496 | } | - | ||||||||||||||||||
| 497 | locker.unlock(); | - | ||||||||||||||||||
| 498 | - | |||||||||||||||||||
| 499 | QEventLoop eventLoop; | - | ||||||||||||||||||
| 500 | int returnCode = eventLoop.exec(); | - | ||||||||||||||||||
| 501 | - | |||||||||||||||||||
| 502 | locker.relock(); | - | ||||||||||||||||||
| 503 | d->exited = false; | - | ||||||||||||||||||
| 504 | d->returnCode = -1; | - | ||||||||||||||||||
| 505 | return returnCode; executed 943 times by 188 tests: return returnCode;Executed by:
| 943 | ||||||||||||||||||
| 506 | } | - | ||||||||||||||||||
| 507 | - | |||||||||||||||||||
| 508 | /*! | - | ||||||||||||||||||
| 509 | Tells the thread's event loop to exit with a return code. | - | ||||||||||||||||||
| 510 | - | |||||||||||||||||||
| 511 | After calling this function, the thread leaves the event loop and | - | ||||||||||||||||||
| 512 | returns from the call to QEventLoop::exec(). The | - | ||||||||||||||||||
| 513 | QEventLoop::exec() function returns \a returnCode. | - | ||||||||||||||||||
| 514 | - | |||||||||||||||||||
| 515 | By convention, a \a returnCode of 0 means success, any non-zero value | - | ||||||||||||||||||
| 516 | indicates an error. | - | ||||||||||||||||||
| 517 | - | |||||||||||||||||||
| 518 | Note that unlike the C library function of the same name, this | - | ||||||||||||||||||
| 519 | function \e does return to the caller -- it is event processing | - | ||||||||||||||||||
| 520 | that stops. | - | ||||||||||||||||||
| 521 | - | |||||||||||||||||||
| 522 | No QEventLoops will be started anymore in this thread until | - | ||||||||||||||||||
| 523 | QThread::exec() has been called again. If the eventloop in QThread::exec() | - | ||||||||||||||||||
| 524 | is not running then the next call to QThread::exec() will also return | - | ||||||||||||||||||
| 525 | immediately. | - | ||||||||||||||||||
| 526 | - | |||||||||||||||||||
| 527 | \sa quit(), QEventLoop | - | ||||||||||||||||||
| 528 | */ | - | ||||||||||||||||||
| 529 | void QThread::exit(int returnCode) | - | ||||||||||||||||||
| 530 | { | - | ||||||||||||||||||
| 531 | Q_D(QThread); | - | ||||||||||||||||||
| 532 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 533 | d->exited = true; | - | ||||||||||||||||||
| 534 | d->returnCode = returnCode; | - | ||||||||||||||||||
| 535 | d->data->quitNow = true; | - | ||||||||||||||||||
| 536 | for (int i = 0; i < d->data->eventLoops.size(); ++i) {
| 947-982 | ||||||||||||||||||
| 537 | QEventLoop *eventLoop = d->data->eventLoops.at(i); | - | ||||||||||||||||||
| 538 | eventLoop->exit(returnCode); | - | ||||||||||||||||||
| 539 | } executed 947 times by 188 tests: end of blockExecuted by:
| 947 | ||||||||||||||||||
| 540 | } executed 982 times by 188 tests: end of blockExecuted by:
| 982 | ||||||||||||||||||
| 541 | - | |||||||||||||||||||
| 542 | /*! | - | ||||||||||||||||||
| 543 | Tells the thread's event loop to exit with return code 0 (success). | - | ||||||||||||||||||
| 544 | Equivalent to calling QThread::exit(0). | - | ||||||||||||||||||
| 545 | - | |||||||||||||||||||
| 546 | This function does nothing if the thread does not have an event | - | ||||||||||||||||||
| 547 | loop. | - | ||||||||||||||||||
| 548 | - | |||||||||||||||||||
| 549 | \sa exit(), QEventLoop | - | ||||||||||||||||||
| 550 | */ | - | ||||||||||||||||||
| 551 | void QThread::quit() | - | ||||||||||||||||||
| 552 | { executed 915 times by 186 tests: exit(); }exit();Executed by:
executed 915 times by 186 tests: exit();Executed by:
| 915 | ||||||||||||||||||
| 553 | - | |||||||||||||||||||
| 554 | /*! | - | ||||||||||||||||||
| 555 | The starting point for the thread. After calling start(), the | - | ||||||||||||||||||
| 556 | newly created thread calls this function. The default | - | ||||||||||||||||||
| 557 | implementation simply calls exec(). | - | ||||||||||||||||||
| 558 | - | |||||||||||||||||||
| 559 | You can reimplement this function to facilitate advanced thread | - | ||||||||||||||||||
| 560 | management. Returning from this method will end the execution of | - | ||||||||||||||||||
| 561 | the thread. | - | ||||||||||||||||||
| 562 | - | |||||||||||||||||||
| 563 | \sa start(), wait() | - | ||||||||||||||||||
| 564 | */ | - | ||||||||||||||||||
| 565 | void QThread::run() | - | ||||||||||||||||||
| 566 | { | - | ||||||||||||||||||
| 567 | (void) exec(); | - | ||||||||||||||||||
| 568 | } executed 649 times by 38 tests: end of blockExecuted by:
| 649 | ||||||||||||||||||
| 569 | - | |||||||||||||||||||
| 570 | /*! \fn void QThread::setPriority(Priority priority) | - | ||||||||||||||||||
| 571 | \since 4.1 | - | ||||||||||||||||||
| 572 | - | |||||||||||||||||||
| 573 | This function sets the \a priority for a running thread. If the | - | ||||||||||||||||||
| 574 | thread is not running, this function does nothing and returns | - | ||||||||||||||||||
| 575 | immediately. Use start() to start a thread with a specific | - | ||||||||||||||||||
| 576 | priority. | - | ||||||||||||||||||
| 577 | - | |||||||||||||||||||
| 578 | The \a priority argument can be any value in the \c | - | ||||||||||||||||||
| 579 | QThread::Priority enum except for \c InheritPriorty. | - | ||||||||||||||||||
| 580 | - | |||||||||||||||||||
| 581 | The effect of the \a priority parameter is dependent on the | - | ||||||||||||||||||
| 582 | operating system's scheduling policy. In particular, the \a priority | - | ||||||||||||||||||
| 583 | will be ignored on systems that do not support thread priorities | - | ||||||||||||||||||
| 584 | (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler | - | ||||||||||||||||||
| 585 | for more details). | - | ||||||||||||||||||
| 586 | - | |||||||||||||||||||
| 587 | \sa Priority, priority(), start() | - | ||||||||||||||||||
| 588 | */ | - | ||||||||||||||||||
| 589 | void QThread::setPriority(Priority priority) | - | ||||||||||||||||||
| 590 | { | - | ||||||||||||||||||
| 591 | Q_D(QThread); | - | ||||||||||||||||||
| 592 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 593 | if (!d->running) {
| 14 | ||||||||||||||||||
| 594 | qWarning("QThread::setPriority: Cannot set priority, thread is not running"); | - | ||||||||||||||||||
| 595 | return; executed 14 times by 1 test: return;Executed by:
| 14 | ||||||||||||||||||
| 596 | } | - | ||||||||||||||||||
| 597 | d->setPriority(priority); | - | ||||||||||||||||||
| 598 | } executed 14 times by 1 test: end of blockExecuted by:
| 14 | ||||||||||||||||||
| 599 | - | |||||||||||||||||||
| 600 | /*! | - | ||||||||||||||||||
| 601 | \since 4.1 | - | ||||||||||||||||||
| 602 | - | |||||||||||||||||||
| 603 | Returns the priority for a running thread. If the thread is not | - | ||||||||||||||||||
| 604 | running, this function returns \c InheritPriority. | - | ||||||||||||||||||
| 605 | - | |||||||||||||||||||
| 606 | \sa Priority, setPriority(), start() | - | ||||||||||||||||||
| 607 | */ | - | ||||||||||||||||||
| 608 | QThread::Priority QThread::priority() const | - | ||||||||||||||||||
| 609 | { | - | ||||||||||||||||||
| 610 | Q_D(const QThread); | - | ||||||||||||||||||
| 611 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 612 | - | |||||||||||||||||||
| 613 | // mask off the high bits that are used for flags | - | ||||||||||||||||||
| 614 | return Priority(d->priority & 0xffff); executed 33 times by 1 test: return Priority(d->priority & 0xffff);Executed by:
| 33 | ||||||||||||||||||
| 615 | } | - | ||||||||||||||||||
| 616 | - | |||||||||||||||||||
| 617 | /*! | - | ||||||||||||||||||
| 618 | \fn void QThread::sleep(unsigned long secs) | - | ||||||||||||||||||
| 619 | - | |||||||||||||||||||
| 620 | Forces the current thread to sleep for \a secs seconds. | - | ||||||||||||||||||
| 621 | - | |||||||||||||||||||
| 622 | \sa msleep(), usleep() | - | ||||||||||||||||||
| 623 | */ | - | ||||||||||||||||||
| 624 | - | |||||||||||||||||||
| 625 | /*! | - | ||||||||||||||||||
| 626 | \fn void QThread::msleep(unsigned long msecs) | - | ||||||||||||||||||
| 627 | - | |||||||||||||||||||
| 628 | Forces the current thread to sleep for \a msecs milliseconds. | - | ||||||||||||||||||
| 629 | - | |||||||||||||||||||
| 630 | \sa sleep(), usleep() | - | ||||||||||||||||||
| 631 | */ | - | ||||||||||||||||||
| 632 | - | |||||||||||||||||||
| 633 | /*! | - | ||||||||||||||||||
| 634 | \fn void QThread::usleep(unsigned long usecs) | - | ||||||||||||||||||
| 635 | - | |||||||||||||||||||
| 636 | Forces the current thread to sleep for \a usecs microseconds. | - | ||||||||||||||||||
| 637 | - | |||||||||||||||||||
| 638 | \sa sleep(), msleep() | - | ||||||||||||||||||
| 639 | */ | - | ||||||||||||||||||
| 640 | - | |||||||||||||||||||
| 641 | /*! | - | ||||||||||||||||||
| 642 | \fn void QThread::terminate() | - | ||||||||||||||||||
| 643 | - | |||||||||||||||||||
| 644 | Terminates the execution of the thread. The thread may or may not | - | ||||||||||||||||||
| 645 | be terminated immediately, depending on the operating system's | - | ||||||||||||||||||
| 646 | scheduling policies. Use QThread::wait() after terminate(), to be | - | ||||||||||||||||||
| 647 | sure. | - | ||||||||||||||||||
| 648 | - | |||||||||||||||||||
| 649 | When the thread is terminated, all threads waiting for the thread | - | ||||||||||||||||||
| 650 | to finish will be woken up. | - | ||||||||||||||||||
| 651 | - | |||||||||||||||||||
| 652 | \warning This function is dangerous and its use is discouraged. | - | ||||||||||||||||||
| 653 | The thread can be terminated at any point in its code path. | - | ||||||||||||||||||
| 654 | Threads can be terminated while modifying data. There is no | - | ||||||||||||||||||
| 655 | chance for the thread to clean up after itself, unlock any held | - | ||||||||||||||||||
| 656 | mutexes, etc. In short, use this function only if absolutely | - | ||||||||||||||||||
| 657 | necessary. | - | ||||||||||||||||||
| 658 | - | |||||||||||||||||||
| 659 | Termination can be explicitly enabled or disabled by calling | - | ||||||||||||||||||
| 660 | QThread::setTerminationEnabled(). Calling this function while | - | ||||||||||||||||||
| 661 | termination is disabled results in the termination being | - | ||||||||||||||||||
| 662 | deferred, until termination is re-enabled. See the documentation | - | ||||||||||||||||||
| 663 | of QThread::setTerminationEnabled() for more information. | - | ||||||||||||||||||
| 664 | - | |||||||||||||||||||
| 665 | \sa setTerminationEnabled() | - | ||||||||||||||||||
| 666 | */ | - | ||||||||||||||||||
| 667 | - | |||||||||||||||||||
| 668 | /*! | - | ||||||||||||||||||
| 669 | \fn bool QThread::wait(unsigned long time) | - | ||||||||||||||||||
| 670 | - | |||||||||||||||||||
| 671 | Blocks the thread until either of these conditions is met: | - | ||||||||||||||||||
| 672 | - | |||||||||||||||||||
| 673 | \list | - | ||||||||||||||||||
| 674 | \li The thread associated with this QThread object has finished | - | ||||||||||||||||||
| 675 | execution (i.e. when it returns from \l{run()}). This function | - | ||||||||||||||||||
| 676 | will return true if the thread has finished. It also returns | - | ||||||||||||||||||
| 677 | true if the thread has not been started yet. | - | ||||||||||||||||||
| 678 | \li \a time milliseconds has elapsed. If \a time is ULONG_MAX (the | - | ||||||||||||||||||
| 679 | default), then the wait will never timeout (the thread must | - | ||||||||||||||||||
| 680 | return from \l{run()}). This function will return false if the | - | ||||||||||||||||||
| 681 | wait timed out. | - | ||||||||||||||||||
| 682 | \endlist | - | ||||||||||||||||||
| 683 | - | |||||||||||||||||||
| 684 | This provides similar functionality to the POSIX \c | - | ||||||||||||||||||
| 685 | pthread_join() function. | - | ||||||||||||||||||
| 686 | - | |||||||||||||||||||
| 687 | \sa sleep(), terminate() | - | ||||||||||||||||||
| 688 | */ | - | ||||||||||||||||||
| 689 | - | |||||||||||||||||||
| 690 | /*! | - | ||||||||||||||||||
| 691 | \fn void QThread::setTerminationEnabled(bool enabled) | - | ||||||||||||||||||
| 692 | - | |||||||||||||||||||
| 693 | Enables or disables termination of the current thread based on the | - | ||||||||||||||||||
| 694 | \a enabled parameter. The thread must have been started by | - | ||||||||||||||||||
| 695 | QThread. | - | ||||||||||||||||||
| 696 | - | |||||||||||||||||||
| 697 | When \a enabled is false, termination is disabled. Future calls | - | ||||||||||||||||||
| 698 | to QThread::terminate() will return immediately without effect. | - | ||||||||||||||||||
| 699 | Instead, the termination is deferred until termination is enabled. | - | ||||||||||||||||||
| 700 | - | |||||||||||||||||||
| 701 | When \a enabled is true, termination is enabled. Future calls to | - | ||||||||||||||||||
| 702 | QThread::terminate() will terminate the thread normally. If | - | ||||||||||||||||||
| 703 | termination has been deferred (i.e. QThread::terminate() was | - | ||||||||||||||||||
| 704 | called with termination disabled), this function will terminate | - | ||||||||||||||||||
| 705 | the calling thread \e immediately. Note that this function will | - | ||||||||||||||||||
| 706 | not return in this case. | - | ||||||||||||||||||
| 707 | - | |||||||||||||||||||
| 708 | \sa terminate() | - | ||||||||||||||||||
| 709 | */ | - | ||||||||||||||||||
| 710 | - | |||||||||||||||||||
| 711 | /*! | - | ||||||||||||||||||
| 712 | \since 5.5 | - | ||||||||||||||||||
| 713 | Returns the current event loop level for the thread. | - | ||||||||||||||||||
| 714 | - | |||||||||||||||||||
| 715 | \note This can only be called within the thread itself, i.e. when | - | ||||||||||||||||||
| 716 | it is the current thread. | - | ||||||||||||||||||
| 717 | */ | - | ||||||||||||||||||
| 718 | - | |||||||||||||||||||
| 719 | int QThread::loopLevel() const | - | ||||||||||||||||||
| 720 | { | - | ||||||||||||||||||
| 721 | Q_D(const QThread); | - | ||||||||||||||||||
| 722 | return d->data->eventLoops.size(); never executed: return d->data->eventLoops.size(); | 0 | ||||||||||||||||||
| 723 | } | - | ||||||||||||||||||
| 724 | - | |||||||||||||||||||
| 725 | #else // QT_NO_THREAD | - | ||||||||||||||||||
| 726 | - | |||||||||||||||||||
| 727 | QThread::QThread(QObject *parent) | - | ||||||||||||||||||
| 728 | : QObject(*(new QThreadPrivate), (QObject*)0){ | - | ||||||||||||||||||
| 729 | Q_D(QThread); | - | ||||||||||||||||||
| 730 | d->data->thread = this; | - | ||||||||||||||||||
| 731 | } | - | ||||||||||||||||||
| 732 | - | |||||||||||||||||||
| 733 | QThread *QThread::currentThread() | - | ||||||||||||||||||
| 734 | { | - | ||||||||||||||||||
| 735 | return QThreadData::current()->thread; | - | ||||||||||||||||||
| 736 | } | - | ||||||||||||||||||
| 737 | - | |||||||||||||||||||
| 738 | QThreadData* QThreadData::current() | - | ||||||||||||||||||
| 739 | { | - | ||||||||||||||||||
| 740 | static QThreadData *data = 0; // reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); | - | ||||||||||||||||||
| 741 | if (!data) { | - | ||||||||||||||||||
| 742 | QScopedPointer<QThreadData> newdata(new QThreadData); | - | ||||||||||||||||||
| 743 | newdata->thread = new QAdoptedThread(newdata.data()); | - | ||||||||||||||||||
| 744 | data = newdata.take(); | - | ||||||||||||||||||
| 745 | data->deref(); | - | ||||||||||||||||||
| 746 | } | - | ||||||||||||||||||
| 747 | return data; | - | ||||||||||||||||||
| 748 | } | - | ||||||||||||||||||
| 749 | - | |||||||||||||||||||
| 750 | /*! | - | ||||||||||||||||||
| 751 | \internal | - | ||||||||||||||||||
| 752 | */ | - | ||||||||||||||||||
| 753 | QThread::QThread(QThreadPrivate &dd, QObject *parent) | - | ||||||||||||||||||
| 754 | : QObject(dd, parent) | - | ||||||||||||||||||
| 755 | { | - | ||||||||||||||||||
| 756 | Q_D(QThread); | - | ||||||||||||||||||
| 757 | // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); | - | ||||||||||||||||||
| 758 | d->data->thread = this; | - | ||||||||||||||||||
| 759 | } | - | ||||||||||||||||||
| 760 | - | |||||||||||||||||||
| 761 | #endif // QT_NO_THREAD | - | ||||||||||||||||||
| 762 | - | |||||||||||||||||||
| 763 | /*! | - | ||||||||||||||||||
| 764 | \since 5.0 | - | ||||||||||||||||||
| 765 | - | |||||||||||||||||||
| 766 | Returns a pointer to the event dispatcher object for the thread. If no event | - | ||||||||||||||||||
| 767 | dispatcher exists for the thread, this function returns 0. | - | ||||||||||||||||||
| 768 | */ | - | ||||||||||||||||||
| 769 | QAbstractEventDispatcher *QThread::eventDispatcher() const | - | ||||||||||||||||||
| 770 | { | - | ||||||||||||||||||
| 771 | Q_D(const QThread); | - | ||||||||||||||||||
| 772 | return d->data->eventDispatcher.load(); executed 192 times by 132 tests: return d->data->eventDispatcher.load();Executed by:
| 192 | ||||||||||||||||||
| 773 | } | - | ||||||||||||||||||
| 774 | - | |||||||||||||||||||
| 775 | /*! | - | ||||||||||||||||||
| 776 | \since 5.0 | - | ||||||||||||||||||
| 777 | - | |||||||||||||||||||
| 778 | Sets the event dispatcher for the thread to \a eventDispatcher. This is | - | ||||||||||||||||||
| 779 | only possible as long as there is no event dispatcher installed for the | - | ||||||||||||||||||
| 780 | thread yet. That is, before the thread has been started with start() or, in | - | ||||||||||||||||||
| 781 | case of the main thread, before QCoreApplication has been instantiated. | - | ||||||||||||||||||
| 782 | This method takes ownership of the object. | - | ||||||||||||||||||
| 783 | */ | - | ||||||||||||||||||
| 784 | void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) | - | ||||||||||||||||||
| 785 | { | - | ||||||||||||||||||
| 786 | Q_D(QThread); | - | ||||||||||||||||||
| 787 | if (d->data->hasEventDispatcher()) {
| 0-3 | ||||||||||||||||||
| 788 | qWarning("QThread::setEventDispatcher: An event dispatcher has already been created for this thread"); | - | ||||||||||||||||||
| 789 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 790 | eventDispatcher->moveToThread(this); | - | ||||||||||||||||||
| 791 | if (eventDispatcher->thread() == this) // was the move successful?
| 0-3 | ||||||||||||||||||
| 792 | d->data->eventDispatcher = eventDispatcher; executed 3 times by 3 tests: d->data->eventDispatcher = eventDispatcher;Executed by:
| 3 | ||||||||||||||||||
| 793 | else | - | ||||||||||||||||||
| 794 | qWarning("QThread::setEventDispatcher: Could not move event dispatcher to target thread"); never executed: QMessageLogger(__FILE__, 794, __PRETTY_FUNCTION__).warning("QThread::setEventDispatcher: Could not move event dispatcher to target thread"); | 0 | ||||||||||||||||||
| 795 | } | - | ||||||||||||||||||
| 796 | } | - | ||||||||||||||||||
| 797 | - | |||||||||||||||||||
| 798 | /*! | - | ||||||||||||||||||
| 799 | \reimp | - | ||||||||||||||||||
| 800 | */ | - | ||||||||||||||||||
| 801 | bool QThread::event(QEvent *event) | - | ||||||||||||||||||
| 802 | { | - | ||||||||||||||||||
| 803 | if (event->type() == QEvent::Quit) {
| 1-3068 | ||||||||||||||||||
| 804 | quit(); | - | ||||||||||||||||||
| 805 | return true; executed 1 time by 1 test: return true;Executed by:
| 1 | ||||||||||||||||||
| 806 | } else { | - | ||||||||||||||||||
| 807 | return QObject::event(event); executed 3068 times by 322 tests: return QObject::event(event);Executed by:
| 3068 | ||||||||||||||||||
| 808 | } | - | ||||||||||||||||||
| 809 | } | - | ||||||||||||||||||
| 810 | - | |||||||||||||||||||
| 811 | /*! | - | ||||||||||||||||||
| 812 | \since 5.2 | - | ||||||||||||||||||
| 813 | - | |||||||||||||||||||
| 814 | Request the interruption of the thread. | - | ||||||||||||||||||
| 815 | That request is advisory and it is up to code running on the thread to decide | - | ||||||||||||||||||
| 816 | if and how it should act upon such request. | - | ||||||||||||||||||
| 817 | This function does not stop any event loop running on the thread and | - | ||||||||||||||||||
| 818 | does not terminate it in any way. | - | ||||||||||||||||||
| 819 | - | |||||||||||||||||||
| 820 | \sa isInterruptionRequested() | - | ||||||||||||||||||
| 821 | */ | - | ||||||||||||||||||
| 822 | - | |||||||||||||||||||
| 823 | void QThread::requestInterruption() | - | ||||||||||||||||||
| 824 | { | - | ||||||||||||||||||
| 825 | Q_D(QThread); | - | ||||||||||||||||||
| 826 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 827 | if (!d->running || d->finished || d->isInFinish)
| 0-1 | ||||||||||||||||||
| 828 | return; never executed: return; | 0 | ||||||||||||||||||
| 829 | if (this == QCoreApplicationPrivate::theMainThread) {
| 0-1 | ||||||||||||||||||
| 830 | qWarning("QThread::requestInterruption has no effect on the main thread"); | - | ||||||||||||||||||
| 831 | return; never executed: return; | 0 | ||||||||||||||||||
| 832 | } | - | ||||||||||||||||||
| 833 | d->interruptionRequested = true; | - | ||||||||||||||||||
| 834 | } executed 1 time by 1 test: end of blockExecuted by:
| 1 | ||||||||||||||||||
| 835 | - | |||||||||||||||||||
| 836 | /*! | - | ||||||||||||||||||
| 837 | \since 5.2 | - | ||||||||||||||||||
| 838 | - | |||||||||||||||||||
| 839 | Return true if the task running on this thread should be stopped. | - | ||||||||||||||||||
| 840 | An interruption can be requested by requestInterruption(). | - | ||||||||||||||||||
| 841 | - | |||||||||||||||||||
| 842 | This function can be used to make long running tasks cleanly interruptible. | - | ||||||||||||||||||
| 843 | Never checking or acting on the value returned by this function is safe, | - | ||||||||||||||||||
| 844 | however it is advisable do so regularly in long running functions. | - | ||||||||||||||||||
| 845 | Take care not to call it too often, to keep the overhead low. | - | ||||||||||||||||||
| 846 | - | |||||||||||||||||||
| 847 | \code | - | ||||||||||||||||||
| 848 | void long_task() { | - | ||||||||||||||||||
| 849 | forever { | - | ||||||||||||||||||
| 850 | if ( QThread::currentThread()->isInterruptionRequested() ) { | - | ||||||||||||||||||
| 851 | return; | - | ||||||||||||||||||
| 852 | } | - | ||||||||||||||||||
| 853 | } | - | ||||||||||||||||||
| 854 | } | - | ||||||||||||||||||
| 855 | \endcode | - | ||||||||||||||||||
| 856 | - | |||||||||||||||||||
| 857 | \sa currentThread() requestInterruption() | - | ||||||||||||||||||
| 858 | */ | - | ||||||||||||||||||
| 859 | bool QThread::isInterruptionRequested() const | - | ||||||||||||||||||
| 860 | { | - | ||||||||||||||||||
| 861 | Q_D(const QThread); | - | ||||||||||||||||||
| 862 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
| 863 | if (!d->running || d->finished || d->isInFinish)
| 0-100 | ||||||||||||||||||
| 864 | return false; executed 2 times by 1 test: return false;Executed by:
| 2 | ||||||||||||||||||
| 865 | return d->interruptionRequested; executed 100 times by 1 test: return d->interruptionRequested;Executed by:
| 100 | ||||||||||||||||||
| 866 | } | - | ||||||||||||||||||
| 867 | - | |||||||||||||||||||
| 868 | /*! | - | ||||||||||||||||||
| 869 | \class QDaemonThread | - | ||||||||||||||||||
| 870 | \since 5.5 | - | ||||||||||||||||||
| 871 | \brief The QDaemonThread provides a class to manage threads that outlive QCoreApplication | - | ||||||||||||||||||
| 872 | \internal | - | ||||||||||||||||||
| 873 | - | |||||||||||||||||||
| 874 | Note: don't try to deliver events from the started() signal. | - | ||||||||||||||||||
| 875 | */ | - | ||||||||||||||||||
| 876 | static void setThreadDoesNotRequireCoreApplication() | - | ||||||||||||||||||
| 877 | { | - | ||||||||||||||||||
| 878 | QThreadData::current()->requiresCoreApplication = false; | - | ||||||||||||||||||
| 879 | } executed 188 times by 161 tests: end of blockExecuted by:
| 188 | ||||||||||||||||||
| 880 | - | |||||||||||||||||||
| 881 | QDaemonThread::QDaemonThread(QObject *parent) | - | ||||||||||||||||||
| 882 | : QThread(parent) | - | ||||||||||||||||||
| 883 | { | - | ||||||||||||||||||
| 884 | // QThread::started() is emitted from the thread we start | - | ||||||||||||||||||
| 885 | connect(this, &QThread::started, setThreadDoesNotRequireCoreApplication); | - | ||||||||||||||||||
| 886 | } executed 188 times by 161 tests: end of blockExecuted by:
| 188 | ||||||||||||||||||
| 887 | - | |||||||||||||||||||
| 888 | QDaemonThread::~QDaemonThread() | - | ||||||||||||||||||
| 889 | { | - | ||||||||||||||||||
| 890 | } | - | ||||||||||||||||||
| 891 | - | |||||||||||||||||||
| 892 | QT_END_NAMESPACE | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |