Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qthread_unix.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 | - | |||||||||||||||||||
36 | #include "qplatformdefs.h" | - | ||||||||||||||||||
37 | - | |||||||||||||||||||
38 | #include <private/qcoreapplication_p.h> | - | ||||||||||||||||||
39 | #include <private/qcore_unix_p.h> | - | ||||||||||||||||||
40 | - | |||||||||||||||||||
41 | #if defined(Q_OS_BLACKBERRY) | - | ||||||||||||||||||
42 | # include <private/qeventdispatcher_blackberry_p.h> | - | ||||||||||||||||||
43 | #elif defined(Q_OS_OSX) | - | ||||||||||||||||||
44 | # include <private/qeventdispatcher_cf_p.h> | - | ||||||||||||||||||
45 | # include <private/qeventdispatcher_unix_p.h> | - | ||||||||||||||||||
46 | #else | - | ||||||||||||||||||
47 | # if !defined(QT_NO_GLIB) | - | ||||||||||||||||||
48 | # include "../kernel/qeventdispatcher_glib_p.h" | - | ||||||||||||||||||
49 | # endif | - | ||||||||||||||||||
50 | # include <private/qeventdispatcher_unix_p.h> | - | ||||||||||||||||||
51 | #endif | - | ||||||||||||||||||
52 | - | |||||||||||||||||||
53 | #include "qthreadstorage.h" | - | ||||||||||||||||||
54 | - | |||||||||||||||||||
55 | #include "qthread_p.h" | - | ||||||||||||||||||
56 | - | |||||||||||||||||||
57 | #include "qdebug.h" | - | ||||||||||||||||||
58 | - | |||||||||||||||||||
59 | #include <sched.h> | - | ||||||||||||||||||
60 | #include <errno.h> | - | ||||||||||||||||||
61 | - | |||||||||||||||||||
62 | #ifdef Q_OS_BSD4 | - | ||||||||||||||||||
63 | #include <sys/sysctl.h> | - | ||||||||||||||||||
64 | #endif | - | ||||||||||||||||||
65 | #ifdef Q_OS_VXWORKS | - | ||||||||||||||||||
66 | # if (_WRS_VXWORKS_MAJOR > 6) || ((_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR >= 6)) | - | ||||||||||||||||||
67 | # include <vxCpuLib.h> | - | ||||||||||||||||||
68 | # include <cpuset.h> | - | ||||||||||||||||||
69 | # define QT_VXWORKS_HAS_CPUSET | - | ||||||||||||||||||
70 | # endif | - | ||||||||||||||||||
71 | #endif | - | ||||||||||||||||||
72 | - | |||||||||||||||||||
73 | #ifdef Q_OS_HPUX | - | ||||||||||||||||||
74 | #include <sys/pstat.h> | - | ||||||||||||||||||
75 | #endif | - | ||||||||||||||||||
76 | - | |||||||||||||||||||
77 | #if defined(Q_OS_MAC) | - | ||||||||||||||||||
78 | # ifdef qDebug | - | ||||||||||||||||||
79 | # define old_qDebug qDebug | - | ||||||||||||||||||
80 | # undef qDebug | - | ||||||||||||||||||
81 | # endif | - | ||||||||||||||||||
82 | - | |||||||||||||||||||
83 | # ifdef old_qDebug | - | ||||||||||||||||||
84 | # undef qDebug | - | ||||||||||||||||||
85 | # define qDebug QT_NO_QDEBUG_MACRO | - | ||||||||||||||||||
86 | # undef old_qDebug | - | ||||||||||||||||||
87 | # endif | - | ||||||||||||||||||
88 | #endif | - | ||||||||||||||||||
89 | - | |||||||||||||||||||
90 | #if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) | - | ||||||||||||||||||
91 | #include <sys/prctl.h> | - | ||||||||||||||||||
92 | #endif | - | ||||||||||||||||||
93 | - | |||||||||||||||||||
94 | #if defined(Q_OS_LINUX) && !defined(SCHED_IDLE) | - | ||||||||||||||||||
95 | // from linux/sched.h | - | ||||||||||||||||||
96 | # define SCHED_IDLE 5 | - | ||||||||||||||||||
97 | #endif | - | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | #if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) | - | ||||||||||||||||||
100 | #define QT_HAS_THREAD_PRIORITY_SCHEDULING | - | ||||||||||||||||||
101 | #endif | - | ||||||||||||||||||
102 | - | |||||||||||||||||||
103 | - | |||||||||||||||||||
104 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
105 | - | |||||||||||||||||||
106 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
107 | - | |||||||||||||||||||
108 | Q_STATIC_ASSERT(sizeof(pthread_t) <= sizeof(Qt::HANDLE)); | - | ||||||||||||||||||
109 | - | |||||||||||||||||||
110 | enum { ThreadPriorityResetFlag = 0x80000000 }; | - | ||||||||||||||||||
111 | - | |||||||||||||||||||
112 | #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE) | - | ||||||||||||||||||
113 | /* LSB doesn't have __thread, https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=993 */ | - | ||||||||||||||||||
114 | #define HAVE_TLS | - | ||||||||||||||||||
115 | #endif | - | ||||||||||||||||||
116 | #if defined(Q_CC_XLC) || defined (Q_CC_SUN) | - | ||||||||||||||||||
117 | #define HAVE_TLS | - | ||||||||||||||||||
118 | #endif | - | ||||||||||||||||||
119 | - | |||||||||||||||||||
120 | #ifdef HAVE_TLS | - | ||||||||||||||||||
121 | static __thread QThreadData *currentThreadData = 0; | - | ||||||||||||||||||
122 | #endif | - | ||||||||||||||||||
123 | - | |||||||||||||||||||
124 | static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT; | - | ||||||||||||||||||
125 | static pthread_key_t current_thread_data_key; | - | ||||||||||||||||||
126 | - | |||||||||||||||||||
127 | static void destroy_current_thread_data(void *p) | - | ||||||||||||||||||
128 | { | - | ||||||||||||||||||
129 | #if defined(Q_OS_VXWORKS) | - | ||||||||||||||||||
130 | // Calling setspecific(..., 0) sets the value to 0 for ALL threads. | - | ||||||||||||||||||
131 | // The 'set to 1' workaround adds a bit of an overhead though, | - | ||||||||||||||||||
132 | // since this function is called twice now. | - | ||||||||||||||||||
133 | if (p == (void *)1) | - | ||||||||||||||||||
134 | return; | - | ||||||||||||||||||
135 | #endif | - | ||||||||||||||||||
136 | // POSIX says the value in our key is set to zero before calling | - | ||||||||||||||||||
137 | // this destructor function, so we need to set it back to the | - | ||||||||||||||||||
138 | // right value... | - | ||||||||||||||||||
139 | pthread_setspecific(current_thread_data_key, p); | - | ||||||||||||||||||
140 | QThreadData *data = static_cast<QThreadData *>(p); | - | ||||||||||||||||||
141 | if (data->isAdopted) {
| 17-638678 | ||||||||||||||||||
142 | QThread *thread = data->thread; | - | ||||||||||||||||||
143 | Q_ASSERT(thread); | - | ||||||||||||||||||
144 | QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread)); | - | ||||||||||||||||||
145 | Q_ASSERT(!thread_p->finished); | - | ||||||||||||||||||
146 | thread_p->finish(thread); | - | ||||||||||||||||||
147 | } executed 17 times by 1 test: end of block Executed by:
| 17 | ||||||||||||||||||
148 | data->deref(); | - | ||||||||||||||||||
149 | - | |||||||||||||||||||
150 | // ... but we must reset it to zero before returning so we aren't | - | ||||||||||||||||||
151 | // called again (POSIX allows implementations to call destructor | - | ||||||||||||||||||
152 | // functions repeatedly until all values are zero) | - | ||||||||||||||||||
153 | pthread_setspecific(current_thread_data_key, | - | ||||||||||||||||||
154 | #if defined(Q_OS_VXWORKS) | - | ||||||||||||||||||
155 | (void *)1); | - | ||||||||||||||||||
156 | #else | - | ||||||||||||||||||
157 | 0); | - | ||||||||||||||||||
158 | #endif | - | ||||||||||||||||||
159 | } executed 638695 times by 548 tests: end of block Executed by:
| 638695 | ||||||||||||||||||
160 | - | |||||||||||||||||||
161 | static void create_current_thread_data_key() | - | ||||||||||||||||||
162 | { | - | ||||||||||||||||||
163 | pthread_key_create(¤t_thread_data_key, destroy_current_thread_data); | - | ||||||||||||||||||
164 | } executed 987 times by 15 tests: end of block Executed by:
| 987 | ||||||||||||||||||
165 | - | |||||||||||||||||||
166 | static void destroy_current_thread_data_key() | - | ||||||||||||||||||
167 | { | - | ||||||||||||||||||
168 | pthread_once(¤t_thread_data_once, create_current_thread_data_key); | - | ||||||||||||||||||
169 | pthread_key_delete(current_thread_data_key); | - | ||||||||||||||||||
170 | - | |||||||||||||||||||
171 | // Reset current_thread_data_once in case we end up recreating | - | ||||||||||||||||||
172 | // the thread-data in the rare case of QObject construction | - | ||||||||||||||||||
173 | // after destroying the QThreadData. | - | ||||||||||||||||||
174 | pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT; | - | ||||||||||||||||||
175 | current_thread_data_once = pthread_once_init; | - | ||||||||||||||||||
176 | } never executed: end of block | 0 | ||||||||||||||||||
177 | Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key) never executed: end of block | 0 | ||||||||||||||||||
178 | - | |||||||||||||||||||
179 | - | |||||||||||||||||||
180 | // Utility functions for getting, setting and clearing thread specific data. | - | ||||||||||||||||||
181 | static QThreadData *get_thread_data() | - | ||||||||||||||||||
182 | { | - | ||||||||||||||||||
183 | #ifdef HAVE_TLS | - | ||||||||||||||||||
184 | return currentThreadData; executed 44576249 times by 1080 tests: return currentThreadData; Executed by:
| 44576249 | ||||||||||||||||||
185 | #else | - | ||||||||||||||||||
186 | pthread_once(¤t_thread_data_once, create_current_thread_data_key); | - | ||||||||||||||||||
187 | return reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); | - | ||||||||||||||||||
188 | #endif | - | ||||||||||||||||||
189 | } | - | ||||||||||||||||||
190 | - | |||||||||||||||||||
191 | static void set_thread_data(QThreadData *data) | - | ||||||||||||||||||
192 | { | - | ||||||||||||||||||
193 | #ifdef HAVE_TLS | - | ||||||||||||||||||
194 | currentThreadData = data; | - | ||||||||||||||||||
195 | #endif | - | ||||||||||||||||||
196 | pthread_once(¤t_thread_data_once, create_current_thread_data_key); | - | ||||||||||||||||||
197 | pthread_setspecific(current_thread_data_key, data); | - | ||||||||||||||||||
198 | } executed 640087 times by 556 tests: end of block Executed by:
| 640087 | ||||||||||||||||||
199 | - | |||||||||||||||||||
200 | static void clear_thread_data() | - | ||||||||||||||||||
201 | { | - | ||||||||||||||||||
202 | #ifdef HAVE_TLS | - | ||||||||||||||||||
203 | currentThreadData = 0; | - | ||||||||||||||||||
204 | #endif | - | ||||||||||||||||||
205 | pthread_setspecific(current_thread_data_key, 0); | - | ||||||||||||||||||
206 | } executed 893 times by 347 tests: end of block Executed by:
| 893 | ||||||||||||||||||
207 | - | |||||||||||||||||||
208 | template <typename T> | - | ||||||||||||||||||
209 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, Qt::HANDLE>::Type to_HANDLE(T id) | - | ||||||||||||||||||
210 | { | - | ||||||||||||||||||
211 | return reinterpret_cast<Qt::HANDLE>(static_cast<intptr_t>(id)); executed 14794065 times by 835 tests: return reinterpret_cast<Qt::HANDLE>(static_cast<intptr_t>(id)); Executed by:
| 14794065 | ||||||||||||||||||
212 | } | - | ||||||||||||||||||
213 | - | |||||||||||||||||||
214 | template <typename T> | - | ||||||||||||||||||
215 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type from_HANDLE(Qt::HANDLE id) | - | ||||||||||||||||||
216 | { | - | ||||||||||||||||||
217 | return static_cast<T>(reinterpret_cast<intptr_t>(id)); executed 1277625 times by 1078 tests: return static_cast<T>(reinterpret_cast<intptr_t>(id)); Executed by:
| 1277625 | ||||||||||||||||||
218 | } | - | ||||||||||||||||||
219 | - | |||||||||||||||||||
220 | template <typename T> | - | ||||||||||||||||||
221 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, Qt::HANDLE>::Type to_HANDLE(T id) | - | ||||||||||||||||||
222 | { | - | ||||||||||||||||||
223 | return id; never executed: return id; | 0 | ||||||||||||||||||
224 | } | - | ||||||||||||||||||
225 | - | |||||||||||||||||||
226 | template <typename T> | - | ||||||||||||||||||
227 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, T>::Type from_HANDLE(Qt::HANDLE id) | - | ||||||||||||||||||
228 | { | - | ||||||||||||||||||
229 | return static_cast<T>(id); never executed: return static_cast<T>(id); | 0 | ||||||||||||||||||
230 | } | - | ||||||||||||||||||
231 | - | |||||||||||||||||||
232 | void QThreadData::clearCurrentThreadData() | - | ||||||||||||||||||
233 | { | - | ||||||||||||||||||
234 | clear_thread_data(); | - | ||||||||||||||||||
235 | } executed 893 times by 347 tests: end of block Executed by:
| 893 | ||||||||||||||||||
236 | - | |||||||||||||||||||
237 | QThreadData *QThreadData::current(bool createIfNecessary) | - | ||||||||||||||||||
238 | { | - | ||||||||||||||||||
239 | QThreadData *data = get_thread_data(); | - | ||||||||||||||||||
240 | if (!data && createIfNecessary) {
| 0-44575238 | ||||||||||||||||||
241 | data = new QThreadData; | - | ||||||||||||||||||
242 | QT_TRY { | - | ||||||||||||||||||
243 | set_thread_data(data); | - | ||||||||||||||||||
244 | data->thread = new QAdoptedThread(data); | - | ||||||||||||||||||
245 | } QT_CATCH(...) { executed 1008 times by 19 tests: end of block Executed by:
| 1008 | ||||||||||||||||||
246 | clear_thread_data(); | - | ||||||||||||||||||
247 | data->deref(); | - | ||||||||||||||||||
248 | data = 0; | - | ||||||||||||||||||
249 | QT_RETHROW; never executed: throw; | 0 | ||||||||||||||||||
250 | } | - | ||||||||||||||||||
251 | data->deref(); | - | ||||||||||||||||||
252 | data->isAdopted = true; | - | ||||||||||||||||||
253 | data->threadId = to_HANDLE(pthread_self()); | - | ||||||||||||||||||
254 | if (!QCoreApplicationPrivate::theMainThread)
| 17-991 | ||||||||||||||||||
255 | QCoreApplicationPrivate::theMainThread = data->thread.load(); executed 991 times by 18 tests: QCoreApplicationPrivate::theMainThread = data->thread.load(); Executed by:
| 991 | ||||||||||||||||||
256 | } executed 1008 times by 19 tests: end of block Executed by:
| 1008 | ||||||||||||||||||
257 | return data; executed 44576249 times by 1080 tests: return data; Executed by:
| 44576249 | ||||||||||||||||||
258 | } | - | ||||||||||||||||||
259 | - | |||||||||||||||||||
260 | - | |||||||||||||||||||
261 | void QAdoptedThread::init() | - | ||||||||||||||||||
262 | { | - | ||||||||||||||||||
263 | } | - | ||||||||||||||||||
264 | - | |||||||||||||||||||
265 | /* | - | ||||||||||||||||||
266 | QThreadPrivate | - | ||||||||||||||||||
267 | */ | - | ||||||||||||||||||
268 | - | |||||||||||||||||||
269 | extern "C" { | - | ||||||||||||||||||
270 | typedef void*(*QtThreadCallback)(void*); | - | ||||||||||||||||||
271 | } | - | ||||||||||||||||||
272 | - | |||||||||||||||||||
273 | #endif // QT_NO_THREAD | - | ||||||||||||||||||
274 | - | |||||||||||||||||||
275 | void QThreadPrivate::createEventDispatcher(QThreadData *data) | - | ||||||||||||||||||
276 | { | - | ||||||||||||||||||
277 | #if defined(Q_OS_BLACKBERRY) | - | ||||||||||||||||||
278 | data->eventDispatcher.storeRelease(new QEventDispatcherBlackberry); | - | ||||||||||||||||||
279 | # elif defined(Q_OS_OSX) | - | ||||||||||||||||||
280 | bool ok = false; | - | ||||||||||||||||||
281 | int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok); | - | ||||||||||||||||||
282 | if (ok && value > 0) | - | ||||||||||||||||||
283 | data->eventDispatcher.storeRelease(new QEventDispatcherCoreFoundation); | - | ||||||||||||||||||
284 | else | - | ||||||||||||||||||
285 | data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); | - | ||||||||||||||||||
286 | # elif !defined(QT_NO_GLIB) | - | ||||||||||||||||||
287 | if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
| 0-639080 | ||||||||||||||||||
288 | && qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
| 0-639080 | ||||||||||||||||||
289 | && QEventDispatcherGlib::versionSupported())
| 0-639080 | ||||||||||||||||||
290 | data->eventDispatcher.storeRelease(new QEventDispatcherGlib); executed 639080 times by 545 tests: data->eventDispatcher.storeRelease(new QEventDispatcherGlib); Executed by:
| 639080 | ||||||||||||||||||
291 | else | - | ||||||||||||||||||
292 | data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); never executed: data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); | 0 | ||||||||||||||||||
293 | #else | - | ||||||||||||||||||
294 | data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); | - | ||||||||||||||||||
295 | #endif | - | ||||||||||||||||||
296 | - | |||||||||||||||||||
297 | data->eventDispatcher.load()->startingUp(); | - | ||||||||||||||||||
298 | } executed 639080 times by 545 tests: end of block Executed by:
| 639080 | ||||||||||||||||||
299 | - | |||||||||||||||||||
300 | #ifndef QT_NO_THREAD | - | ||||||||||||||||||
301 | - | |||||||||||||||||||
302 | #if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX)) | - | ||||||||||||||||||
303 | static void setCurrentThreadName(pthread_t threadId, const char *name) | - | ||||||||||||||||||
304 | { | - | ||||||||||||||||||
305 | # if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) | - | ||||||||||||||||||
306 | Q_UNUSED(threadId); | - | ||||||||||||||||||
307 | prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0); | - | ||||||||||||||||||
308 | # elif defined(Q_OS_MAC) | - | ||||||||||||||||||
309 | Q_UNUSED(threadId); | - | ||||||||||||||||||
310 | pthread_setname_np(name); | - | ||||||||||||||||||
311 | # elif defined(Q_OS_QNX) | - | ||||||||||||||||||
312 | pthread_setname_np(threadId, name); | - | ||||||||||||||||||
313 | # endif | - | ||||||||||||||||||
314 | } executed 639079 times by 545 tests: end of block Executed by:
| 639079 | ||||||||||||||||||
315 | #endif | - | ||||||||||||||||||
316 | - | |||||||||||||||||||
317 | void *QThreadPrivate::start(void *arg) | - | ||||||||||||||||||
318 | { | - | ||||||||||||||||||
319 | #if !defined(Q_OS_ANDROID) | - | ||||||||||||||||||
320 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); | - | ||||||||||||||||||
321 | #endif | - | ||||||||||||||||||
322 | pthread_cleanup_push(QThreadPrivate::finish, arg); | - | ||||||||||||||||||
323 | - | |||||||||||||||||||
324 | QThread *thr = reinterpret_cast<QThread *>(arg); | - | ||||||||||||||||||
325 | QThreadData *data = QThreadData::get2(thr); | - | ||||||||||||||||||
326 | - | |||||||||||||||||||
327 | { | - | ||||||||||||||||||
328 | QMutexLocker locker(&thr->d_func()->mutex); | - | ||||||||||||||||||
329 | - | |||||||||||||||||||
330 | // do we need to reset the thread priority? | - | ||||||||||||||||||
331 | if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
| 3-639076 | ||||||||||||||||||
332 | thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); | - | ||||||||||||||||||
333 | } executed 3 times by 2 tests: end of block Executed by:
| 3 | ||||||||||||||||||
334 | - | |||||||||||||||||||
335 | data->threadId = to_HANDLE(pthread_self()); | - | ||||||||||||||||||
336 | set_thread_data(data); | - | ||||||||||||||||||
337 | - | |||||||||||||||||||
338 | data->ref(); | - | ||||||||||||||||||
339 | data->quitNow = thr->d_func()->exited; | - | ||||||||||||||||||
340 | } | - | ||||||||||||||||||
341 | - | |||||||||||||||||||
342 | if (data->eventDispatcher.load()) // custom event dispatcher set?
| 1-639078 | ||||||||||||||||||
343 | data->eventDispatcher.load()->startingUp(); executed 1 time by 1 test: data->eventDispatcher.load()->startingUp(); Executed by:
| 1 | ||||||||||||||||||
344 | else | - | ||||||||||||||||||
345 | createEventDispatcher(data); executed 639078 times by 545 tests: createEventDispatcher(data); Executed by:
| 639078 | ||||||||||||||||||
346 | - | |||||||||||||||||||
347 | #if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX)) | - | ||||||||||||||||||
348 | { | - | ||||||||||||||||||
349 | // sets the name of the current thread. | - | ||||||||||||||||||
350 | QString objectName = thr->objectName(); | - | ||||||||||||||||||
351 | - | |||||||||||||||||||
352 | pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId); | - | ||||||||||||||||||
353 | if (Q_LIKELY(objectName.isEmpty()))
| 1934-637145 | ||||||||||||||||||
354 | setCurrentThreadName(thread_id, thr->metaObject()->className()); executed 637145 times by 545 tests: setCurrentThreadName(thread_id, thr->metaObject()->className()); Executed by:
| 637145 | ||||||||||||||||||
355 | else | - | ||||||||||||||||||
356 | setCurrentThreadName(thread_id, objectName.toLocal8Bit()); executed 1934 times by 45 tests: setCurrentThreadName(thread_id, objectName.toLocal8Bit()); Executed by:
| 1934 | ||||||||||||||||||
357 | } | - | ||||||||||||||||||
358 | #endif | - | ||||||||||||||||||
359 | - | |||||||||||||||||||
360 | emit thr->started(QThread::QPrivateSignal()); | - | ||||||||||||||||||
361 | #if !defined(Q_OS_ANDROID) | - | ||||||||||||||||||
362 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); | - | ||||||||||||||||||
363 | pthread_testcancel(); | - | ||||||||||||||||||
364 | #endif | - | ||||||||||||||||||
365 | thr->run(); | - | ||||||||||||||||||
366 | - | |||||||||||||||||||
367 | pthread_cleanup_pop(1); | - | ||||||||||||||||||
368 | - | |||||||||||||||||||
369 | return 0; executed 638676 times by 548 tests: return 0; Executed by:
| 638676 | ||||||||||||||||||
370 | } | - | ||||||||||||||||||
371 | - | |||||||||||||||||||
372 | void QThreadPrivate::finish(void *arg) | - | ||||||||||||||||||
373 | { | - | ||||||||||||||||||
374 | QThread *thr = reinterpret_cast<QThread *>(arg); | - | ||||||||||||||||||
375 | QThreadPrivate *d = thr->d_func(); | - | ||||||||||||||||||
376 | - | |||||||||||||||||||
377 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
378 | - | |||||||||||||||||||
379 | d->isInFinish = true; | - | ||||||||||||||||||
380 | d->priority = QThread::InheritPriority; | - | ||||||||||||||||||
381 | void *data = &d->data->tls; | - | ||||||||||||||||||
382 | locker.unlock(); | - | ||||||||||||||||||
383 | emit thr->finished(QThread::QPrivateSignal()); | - | ||||||||||||||||||
384 | QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); | - | ||||||||||||||||||
385 | QThreadStorageData::finish((void **)data); | - | ||||||||||||||||||
386 | locker.relock(); | - | ||||||||||||||||||
387 | - | |||||||||||||||||||
388 | QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load(); | - | ||||||||||||||||||
389 | if (eventDispatcher) {
| 15-639248 | ||||||||||||||||||
390 | d->data->eventDispatcher = 0; | - | ||||||||||||||||||
391 | locker.unlock(); | - | ||||||||||||||||||
392 | eventDispatcher->closingDown(); | - | ||||||||||||||||||
393 | delete eventDispatcher; | - | ||||||||||||||||||
394 | locker.relock(); | - | ||||||||||||||||||
395 | } executed 639248 times by 611 tests: end of block Executed by:
| 639248 | ||||||||||||||||||
396 | - | |||||||||||||||||||
397 | d->running = false; | - | ||||||||||||||||||
398 | d->finished = true; | - | ||||||||||||||||||
399 | d->interruptionRequested = false; | - | ||||||||||||||||||
400 | - | |||||||||||||||||||
401 | d->isInFinish = false; | - | ||||||||||||||||||
402 | d->thread_done.wakeAll(); | - | ||||||||||||||||||
403 | } executed 639263 times by 611 tests: end of block Executed by:
| 639263 | ||||||||||||||||||
404 | - | |||||||||||||||||||
405 | - | |||||||||||||||||||
406 | - | |||||||||||||||||||
407 | - | |||||||||||||||||||
408 | /************************************************************************** | - | ||||||||||||||||||
409 | ** QThread | - | ||||||||||||||||||
410 | *************************************************************************/ | - | ||||||||||||||||||
411 | - | |||||||||||||||||||
412 | Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW | - | ||||||||||||||||||
413 | { | - | ||||||||||||||||||
414 | // requires a C cast here otherwise we run into trouble on AIX | - | ||||||||||||||||||
415 | return to_HANDLE(pthread_self()); executed 13514900 times by 600 tests: return to_HANDLE(pthread_self()); Executed by:
| 13514900 | ||||||||||||||||||
416 | } | - | ||||||||||||||||||
417 | - | |||||||||||||||||||
418 | #if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN) | - | ||||||||||||||||||
419 | // LSB doesn't define _SC_NPROCESSORS_ONLN. | - | ||||||||||||||||||
420 | # define _SC_NPROCESSORS_ONLN 84 | - | ||||||||||||||||||
421 | #endif | - | ||||||||||||||||||
422 | - | |||||||||||||||||||
423 | int QThread::idealThreadCount() Q_DECL_NOTHROW | - | ||||||||||||||||||
424 | { | - | ||||||||||||||||||
425 | int cores = 1; | - | ||||||||||||||||||
426 | - | |||||||||||||||||||
427 | #if defined(Q_OS_HPUX) | - | ||||||||||||||||||
428 | // HP-UX | - | ||||||||||||||||||
429 | struct pst_dynamic psd; | - | ||||||||||||||||||
430 | if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1) { | - | ||||||||||||||||||
431 | perror("pstat_getdynamic"); | - | ||||||||||||||||||
432 | } else { | - | ||||||||||||||||||
433 | cores = (int)psd.psd_proc_cnt; | - | ||||||||||||||||||
434 | } | - | ||||||||||||||||||
435 | #elif defined(Q_OS_BSD4) | - | ||||||||||||||||||
436 | // FreeBSD, OpenBSD, NetBSD, BSD/OS, OS X, iOS | - | ||||||||||||||||||
437 | size_t len = sizeof(cores); | - | ||||||||||||||||||
438 | int mib[2]; | - | ||||||||||||||||||
439 | mib[0] = CTL_HW; | - | ||||||||||||||||||
440 | mib[1] = HW_NCPU; | - | ||||||||||||||||||
441 | if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) { | - | ||||||||||||||||||
442 | perror("sysctl"); | - | ||||||||||||||||||
443 | } | - | ||||||||||||||||||
444 | #elif defined(Q_OS_IRIX) | - | ||||||||||||||||||
445 | // IRIX | - | ||||||||||||||||||
446 | cores = (int)sysconf(_SC_NPROC_ONLN); | - | ||||||||||||||||||
447 | #elif defined(Q_OS_INTEGRITY) | - | ||||||||||||||||||
448 | #if (__INTEGRITY_MAJOR_VERSION >= 10) | - | ||||||||||||||||||
449 | // Integrity V10+ does support multicore CPUs | - | ||||||||||||||||||
450 | Value processorCount; | - | ||||||||||||||||||
451 | if (GetProcessorCount(CurrentTask(), &processorCount) == 0) | - | ||||||||||||||||||
452 | cores = processorCount; | - | ||||||||||||||||||
453 | else | - | ||||||||||||||||||
454 | #endif | - | ||||||||||||||||||
455 | // as of aug 2008 Integrity only supports one single core CPU | - | ||||||||||||||||||
456 | cores = 1; | - | ||||||||||||||||||
457 | #elif defined(Q_OS_VXWORKS) | - | ||||||||||||||||||
458 | // VxWorks | - | ||||||||||||||||||
459 | # if defined(QT_VXWORKS_HAS_CPUSET) | - | ||||||||||||||||||
460 | cpuset_t cpus = vxCpuEnabledGet(); | - | ||||||||||||||||||
461 | cores = 0; | - | ||||||||||||||||||
462 | - | |||||||||||||||||||
463 | // 128 cores should be enough for everyone ;) | - | ||||||||||||||||||
464 | for (int i = 0; i < 128 && !CPUSET_ISZERO(cpus); ++i) { | - | ||||||||||||||||||
465 | if (CPUSET_ISSET(cpus, i)) { | - | ||||||||||||||||||
466 | CPUSET_CLR(cpus, i); | - | ||||||||||||||||||
467 | cores++; | - | ||||||||||||||||||
468 | } | - | ||||||||||||||||||
469 | } | - | ||||||||||||||||||
470 | # else | - | ||||||||||||||||||
471 | // as of aug 2008 VxWorks < 6.6 only supports one single core CPU | - | ||||||||||||||||||
472 | cores = 1; | - | ||||||||||||||||||
473 | # endif | - | ||||||||||||||||||
474 | #else | - | ||||||||||||||||||
475 | // the rest: Linux, Solaris, AIX, Tru64 | - | ||||||||||||||||||
476 | cores = (int)sysconf(_SC_NPROCESSORS_ONLN); | - | ||||||||||||||||||
477 | if (cores == -1)
| 0-1705 | ||||||||||||||||||
478 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
479 | #endif | - | ||||||||||||||||||
480 | return cores; executed 1705 times by 448 tests: return cores; Executed by:
| 1705 | ||||||||||||||||||
481 | } | - | ||||||||||||||||||
482 | - | |||||||||||||||||||
483 | void QThread::yieldCurrentThread() | - | ||||||||||||||||||
484 | { | - | ||||||||||||||||||
485 | sched_yield(); | - | ||||||||||||||||||
486 | } executed 1556 times by 3 tests: end of block Executed by:
| 1556 | ||||||||||||||||||
487 | - | |||||||||||||||||||
488 | static timespec makeTimespec(time_t secs, long nsecs) | - | ||||||||||||||||||
489 | { | - | ||||||||||||||||||
490 | struct timespec ts; | - | ||||||||||||||||||
491 | ts.tv_sec = secs; | - | ||||||||||||||||||
492 | ts.tv_nsec = nsecs; | - | ||||||||||||||||||
493 | return ts; executed 326438 times by 11 tests: return ts; Executed by:
| 326438 | ||||||||||||||||||
494 | } | - | ||||||||||||||||||
495 | - | |||||||||||||||||||
496 | void QThread::sleep(unsigned long secs) | - | ||||||||||||||||||
497 | { | - | ||||||||||||||||||
498 | qt_nanosleep(makeTimespec(secs, 0)); | - | ||||||||||||||||||
499 | } executed 7 times by 3 tests: end of block Executed by:
| 7 | ||||||||||||||||||
500 | - | |||||||||||||||||||
501 | void QThread::msleep(unsigned long msecs) | - | ||||||||||||||||||
502 | { | - | ||||||||||||||||||
503 | qt_nanosleep(makeTimespec(msecs / 1000, msecs % 1000 * 1000 * 1000)); | - | ||||||||||||||||||
504 | } executed 296435 times by 8 tests: end of block Executed by:
| 296435 | ||||||||||||||||||
505 | - | |||||||||||||||||||
506 | void QThread::usleep(unsigned long usecs) | - | ||||||||||||||||||
507 | { | - | ||||||||||||||||||
508 | qt_nanosleep(makeTimespec(usecs / 1000 / 1000, usecs % (1000*1000) * 1000)); | - | ||||||||||||||||||
509 | } executed 29996 times by 3 tests: end of block Executed by:
| 29996 | ||||||||||||||||||
510 | - | |||||||||||||||||||
511 | #ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING | - | ||||||||||||||||||
512 | // Does some magic and calculate the Unix scheduler priorities | - | ||||||||||||||||||
513 | // sched_policy is IN/OUT: it must be set to a valid policy before calling this function | - | ||||||||||||||||||
514 | // sched_priority is OUT only | - | ||||||||||||||||||
515 | static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority) | - | ||||||||||||||||||
516 | { | - | ||||||||||||||||||
517 | #ifdef SCHED_IDLE | - | ||||||||||||||||||
518 | if (priority == QThread::IdlePriority) {
| 8-392 | ||||||||||||||||||
519 | *sched_policy = SCHED_IDLE; | - | ||||||||||||||||||
520 | *sched_priority = 0; | - | ||||||||||||||||||
521 | return true; executed 8 times by 2 tests: return true; Executed by:
| 8 | ||||||||||||||||||
522 | } | - | ||||||||||||||||||
523 | const int lowestPriority = QThread::LowestPriority; | - | ||||||||||||||||||
524 | #else | - | ||||||||||||||||||
525 | const int lowestPriority = QThread::IdlePriority; | - | ||||||||||||||||||
526 | #endif | - | ||||||||||||||||||
527 | const int highestPriority = QThread::TimeCriticalPriority; | - | ||||||||||||||||||
528 | - | |||||||||||||||||||
529 | int prio_min; | - | ||||||||||||||||||
530 | int prio_max; | - | ||||||||||||||||||
531 | #if defined(Q_OS_VXWORKS) && defined(VXWORKS_DKM) | - | ||||||||||||||||||
532 | // for other scheduling policies than SCHED_RR or SCHED_FIFO | - | ||||||||||||||||||
533 | prio_min = SCHED_FIFO_LOW_PRI; | - | ||||||||||||||||||
534 | prio_max = SCHED_FIFO_HIGH_PRI; | - | ||||||||||||||||||
535 | - | |||||||||||||||||||
536 | if ((*sched_policy == SCHED_RR) || (*sched_policy == SCHED_FIFO)) | - | ||||||||||||||||||
537 | #endif | - | ||||||||||||||||||
538 | { | - | ||||||||||||||||||
539 | prio_min = sched_get_priority_min(*sched_policy); | - | ||||||||||||||||||
540 | prio_max = sched_get_priority_max(*sched_policy); | - | ||||||||||||||||||
541 | } | - | ||||||||||||||||||
542 | - | |||||||||||||||||||
543 | if (prio_min == -1 || prio_max == -1)
| 0-392 | ||||||||||||||||||
544 | return false; never executed: return false; | 0 | ||||||||||||||||||
545 | - | |||||||||||||||||||
546 | int prio; | - | ||||||||||||||||||
547 | // crudely scale our priority enum values to the prio_min/prio_max | - | ||||||||||||||||||
548 | prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min; | - | ||||||||||||||||||
549 | prio = qMax(prio_min, qMin(prio_max, prio)); | - | ||||||||||||||||||
550 | - | |||||||||||||||||||
551 | *sched_priority = prio; | - | ||||||||||||||||||
552 | return true; executed 392 times by 10 tests: return true; Executed by:
| 392 | ||||||||||||||||||
553 | } | - | ||||||||||||||||||
554 | #endif | - | ||||||||||||||||||
555 | - | |||||||||||||||||||
556 | void QThread::start(Priority priority) | - | ||||||||||||||||||
557 | { | - | ||||||||||||||||||
558 | Q_D(QThread); | - | ||||||||||||||||||
559 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
560 | - | |||||||||||||||||||
561 | if (d->isInFinish)
| 1-639078 | ||||||||||||||||||
562 | d->thread_done.wait(locker.mutex()); executed 1 time by 1 test: d->thread_done.wait(locker.mutex()); Executed by:
| 1 | ||||||||||||||||||
563 | - | |||||||||||||||||||
564 | if (d->running)
| 1-639078 | ||||||||||||||||||
565 | return; executed 1 time by 1 test: return; Executed by:
| 1 | ||||||||||||||||||
566 | - | |||||||||||||||||||
567 | d->running = true; | - | ||||||||||||||||||
568 | d->finished = false; | - | ||||||||||||||||||
569 | d->returnCode = 0; | - | ||||||||||||||||||
570 | d->exited = false; | - | ||||||||||||||||||
571 | d->interruptionRequested = false; | - | ||||||||||||||||||
572 | - | |||||||||||||||||||
573 | pthread_attr_t attr; | - | ||||||||||||||||||
574 | pthread_attr_init(&attr); | - | ||||||||||||||||||
575 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | - | ||||||||||||||||||
576 | - | |||||||||||||||||||
577 | d->priority = priority; | - | ||||||||||||||||||
578 | - | |||||||||||||||||||
579 | #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) | - | ||||||||||||||||||
580 | switch (priority) { | - | ||||||||||||||||||
581 | case InheritPriority: executed 638695 times by 545 tests: case InheritPriority: Executed by:
| 638695 | ||||||||||||||||||
582 | { | - | ||||||||||||||||||
583 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||||||||||||||
584 | break; executed 638695 times by 545 tests: break; Executed by:
| 638695 | ||||||||||||||||||
585 | } | - | ||||||||||||||||||
586 | - | |||||||||||||||||||
587 | default: executed 383 times by 10 tests: default: Executed by:
| 383 | ||||||||||||||||||
588 | { | - | ||||||||||||||||||
589 | int sched_policy; | - | ||||||||||||||||||
590 | if (pthread_attr_getschedpolicy(&attr, &sched_policy) != 0) {
| 0-383 | ||||||||||||||||||
591 | // failed to get the scheduling policy, don't bother | - | ||||||||||||||||||
592 | // setting the priority | - | ||||||||||||||||||
593 | qWarning("QThread::start: Cannot determine default scheduler policy"); | - | ||||||||||||||||||
594 | break; never executed: break; | 0 | ||||||||||||||||||
595 | } | - | ||||||||||||||||||
596 | - | |||||||||||||||||||
597 | int prio; | - | ||||||||||||||||||
598 | if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
| 0-383 | ||||||||||||||||||
599 | // failed to get the scheduling parameters, don't | - | ||||||||||||||||||
600 | // bother setting the priority | - | ||||||||||||||||||
601 | qWarning("QThread::start: Cannot determine scheduler priority range"); | - | ||||||||||||||||||
602 | break; never executed: break; | 0 | ||||||||||||||||||
603 | } | - | ||||||||||||||||||
604 | - | |||||||||||||||||||
605 | sched_param sp; | - | ||||||||||||||||||
606 | sp.sched_priority = prio; | - | ||||||||||||||||||
607 | - | |||||||||||||||||||
608 | if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0
| 0-383 | ||||||||||||||||||
609 | || pthread_attr_setschedpolicy(&attr, sched_policy) != 0
| 3-380 | ||||||||||||||||||
610 | || pthread_attr_setschedparam(&attr, &sp) != 0) {
| 0-380 | ||||||||||||||||||
611 | // could not set scheduling hints, fallback to inheriting them | - | ||||||||||||||||||
612 | // we'll try again from inside the thread | - | ||||||||||||||||||
613 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||||||||||||||
614 | d->priority = Priority(priority | ThreadPriorityResetFlag); | - | ||||||||||||||||||
615 | } executed 3 times by 2 tests: end of block Executed by:
| 3 | ||||||||||||||||||
616 | break; executed 383 times by 10 tests: break; Executed by:
| 383 | ||||||||||||||||||
617 | } | - | ||||||||||||||||||
618 | } | - | ||||||||||||||||||
619 | #endif // QT_HAS_THREAD_PRIORITY_SCHEDULING | - | ||||||||||||||||||
620 | - | |||||||||||||||||||
621 | - | |||||||||||||||||||
622 | if (d->stackSize > 0) {
| 0-639078 | ||||||||||||||||||
623 | #if defined(_POSIX_THREAD_ATTR_STACKSIZE) && (_POSIX_THREAD_ATTR_STACKSIZE-0 > 0) | - | ||||||||||||||||||
624 | int code = pthread_attr_setstacksize(&attr, d->stackSize); | - | ||||||||||||||||||
625 | #else | - | ||||||||||||||||||
626 | int code = ENOSYS; // stack size not supported, automatically fail | - | ||||||||||||||||||
627 | #endif // _POSIX_THREAD_ATTR_STACKSIZE | - | ||||||||||||||||||
628 | - | |||||||||||||||||||
629 | if (code) {
| 0 | ||||||||||||||||||
630 | qWarning("QThread::start: Thread stack size error: %s", | - | ||||||||||||||||||
631 | qPrintable(qt_error_string(code))); | - | ||||||||||||||||||
632 | - | |||||||||||||||||||
633 | // we failed to set the stacksize, and as the documentation states, | - | ||||||||||||||||||
634 | // the thread will fail to run... | - | ||||||||||||||||||
635 | d->running = false; | - | ||||||||||||||||||
636 | d->finished = false; | - | ||||||||||||||||||
637 | return; never executed: return; | 0 | ||||||||||||||||||
638 | } | - | ||||||||||||||||||
639 | } never executed: end of block | 0 | ||||||||||||||||||
640 | - | |||||||||||||||||||
641 | pthread_t threadId; | - | ||||||||||||||||||
642 | int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); | - | ||||||||||||||||||
643 | if (code == EPERM) {
| 0-639078 | ||||||||||||||||||
644 | // caller does not have permission to set the scheduling | - | ||||||||||||||||||
645 | // parameters/policy | - | ||||||||||||||||||
646 | #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) | - | ||||||||||||||||||
647 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||||||||||||||
648 | #endif | - | ||||||||||||||||||
649 | code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); | - | ||||||||||||||||||
650 | } never executed: end of block | 0 | ||||||||||||||||||
651 | d->data->threadId = to_HANDLE(threadId); | - | ||||||||||||||||||
652 | - | |||||||||||||||||||
653 | pthread_attr_destroy(&attr); | - | ||||||||||||||||||
654 | - | |||||||||||||||||||
655 | if (code) {
| 0-639078 | ||||||||||||||||||
656 | qWarning("QThread::start: Thread creation error: %s", qPrintable(qt_error_string(code))); | - | ||||||||||||||||||
657 | - | |||||||||||||||||||
658 | d->running = false; | - | ||||||||||||||||||
659 | d->finished = false; | - | ||||||||||||||||||
660 | d->data->threadId = 0; | - | ||||||||||||||||||
661 | } never executed: end of block | 0 | ||||||||||||||||||
662 | } executed 639078 times by 545 tests: end of block Executed by:
| 639078 | ||||||||||||||||||
663 | - | |||||||||||||||||||
664 | void QThread::terminate() | - | ||||||||||||||||||
665 | { | - | ||||||||||||||||||
666 | #if !defined(Q_OS_ANDROID) | - | ||||||||||||||||||
667 | Q_D(QThread); | - | ||||||||||||||||||
668 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
669 | - | |||||||||||||||||||
670 | if (!d->data->threadId)
| 0-2 | ||||||||||||||||||
671 | return; never executed: return; | 0 | ||||||||||||||||||
672 | - | |||||||||||||||||||
673 | int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId)); | - | ||||||||||||||||||
674 | if (code) {
| 0-2 | ||||||||||||||||||
675 | qWarning("QThread::start: Thread termination error: %s", | - | ||||||||||||||||||
676 | qPrintable(qt_error_string((code)))); | - | ||||||||||||||||||
677 | } never executed: end of block | 0 | ||||||||||||||||||
678 | #endif | - | ||||||||||||||||||
679 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
680 | - | |||||||||||||||||||
681 | bool QThread::wait(unsigned long time) | - | ||||||||||||||||||
682 | { | - | ||||||||||||||||||
683 | Q_D(QThread); | - | ||||||||||||||||||
684 | QMutexLocker locker(&d->mutex); | - | ||||||||||||||||||
685 | - | |||||||||||||||||||
686 | if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) {
| 0-638510 | ||||||||||||||||||
687 | qWarning("QThread::wait: Thread tried to wait on itself"); | - | ||||||||||||||||||
688 | return false; never executed: return false; | 0 | ||||||||||||||||||
689 | } | - | ||||||||||||||||||
690 | - | |||||||||||||||||||
691 | if (d->finished || !d->running)
| 10-631763 | ||||||||||||||||||
692 | return true; executed 6757 times by 471 tests: return true; Executed by:
| 6757 | ||||||||||||||||||
693 | - | |||||||||||||||||||
694 | while (d->running) {
| 631680-631753 | ||||||||||||||||||
695 | if (!d->thread_done.wait(locker.mutex(), time))
| 73-631680 | ||||||||||||||||||
696 | return false; executed 73 times by 4 tests: return false; Executed by:
| 73 | ||||||||||||||||||
697 | } executed 631680 times by 231 tests: end of block Executed by:
| 631680 | ||||||||||||||||||
698 | return true; executed 631680 times by 231 tests: return true; Executed by:
| 631680 | ||||||||||||||||||
699 | } | - | ||||||||||||||||||
700 | - | |||||||||||||||||||
701 | void QThread::setTerminationEnabled(bool enabled) | - | ||||||||||||||||||
702 | { | - | ||||||||||||||||||
703 | QThread *thr = currentThread(); | - | ||||||||||||||||||
704 | Q_ASSERT_X(thr != 0, "QThread::setTerminationEnabled()", | - | ||||||||||||||||||
705 | "Current thread was not started with QThread."); | - | ||||||||||||||||||
706 | - | |||||||||||||||||||
707 | Q_UNUSED(thr) | - | ||||||||||||||||||
708 | #if defined(Q_OS_ANDROID) | - | ||||||||||||||||||
709 | Q_UNUSED(enabled); | - | ||||||||||||||||||
710 | #else | - | ||||||||||||||||||
711 | pthread_setcancelstate(enabled ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE, NULL); | - | ||||||||||||||||||
712 | if (enabled)
| 2-166 | ||||||||||||||||||
713 | pthread_testcancel(); executed 166 times by 2 tests: pthread_testcancel(); Executed by:
| 166 | ||||||||||||||||||
714 | #endif | - | ||||||||||||||||||
715 | } executed 166 times by 2 tests: end of block Executed by:
| 166 | ||||||||||||||||||
716 | - | |||||||||||||||||||
717 | // Caller must lock the mutex | - | ||||||||||||||||||
718 | void QThreadPrivate::setPriority(QThread::Priority threadPriority) | - | ||||||||||||||||||
719 | { | - | ||||||||||||||||||
720 | priority = threadPriority; | - | ||||||||||||||||||
721 | - | |||||||||||||||||||
722 | // copied from start() with a few modifications: | - | ||||||||||||||||||
723 | - | |||||||||||||||||||
724 | #ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING | - | ||||||||||||||||||
725 | int sched_policy; | - | ||||||||||||||||||
726 | sched_param param; | - | ||||||||||||||||||
727 | - | |||||||||||||||||||
728 | if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m) != 0) {
| 0-17 | ||||||||||||||||||
729 | // failed to get the scheduling policy, don't bother setting | - | ||||||||||||||||||
730 | // the priority | - | ||||||||||||||||||
731 | qWarning("QThread::setPriority: Cannot get scheduler parameters"); | - | ||||||||||||||||||
732 | return; never executed: return; | 0 | ||||||||||||||||||
733 | } | - | ||||||||||||||||||
734 | - | |||||||||||||||||||
735 | int prio; | - | ||||||||||||||||||
736 | if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
| 0-17 | ||||||||||||||||||
737 | // failed to get the scheduling parameters, don't | - | ||||||||||||||||||
738 | // bother setting the priority | - | ||||||||||||||||||
739 | qWarning("QThread::setPriority: Cannot determine scheduler priority range"); | - | ||||||||||||||||||
740 | return; never executed: return; | 0 | ||||||||||||||||||
741 | } | - | ||||||||||||||||||
742 | - | |||||||||||||||||||
743 | param.sched_priority = prio; | - | ||||||||||||||||||
744 | int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); | - | ||||||||||||||||||
745 | - | |||||||||||||||||||
746 | # ifdef SCHED_IDLE | - | ||||||||||||||||||
747 | // were we trying to set to idle priority and failed? | - | ||||||||||||||||||
748 | if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
| 0-17 | ||||||||||||||||||
749 | // reset to lowest priority possible | - | ||||||||||||||||||
750 | pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m); | - | ||||||||||||||||||
751 | param.sched_priority = sched_get_priority_min(sched_policy); | - | ||||||||||||||||||
752 | pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); | - | ||||||||||||||||||
753 | } never executed: end of block | 0 | ||||||||||||||||||
754 | # else | - | ||||||||||||||||||
755 | Q_UNUSED(status); | - | ||||||||||||||||||
756 | # endif // SCHED_IDLE | - | ||||||||||||||||||
757 | #endif | - | ||||||||||||||||||
758 | } executed 17 times by 2 tests: end of block Executed by:
| 17 | ||||||||||||||||||
759 | - | |||||||||||||||||||
760 | #endif // QT_NO_THREAD | - | ||||||||||||||||||
761 | - | |||||||||||||||||||
762 | QT_END_NAMESPACE | - | ||||||||||||||||||
763 | - | |||||||||||||||||||
Source code | Switch to Preprocessed file |