| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qthread_unix.cpp | 
| Switch to Source code | Preprocessed file | 
| Line | Source | Count | ||||||
|---|---|---|---|---|---|---|---|---|
| 1 | - | |||||||
| 2 | - | |||||||
| 3 | - | |||||||
| 4 | - | |||||||
| 5 | - | |||||||
| 6 | - | |||||||
| 7 | - | |||||||
| 8 | - | |||||||
| 9 | - | |||||||
| 10 | - | |||||||
| 11 | - | |||||||
| 12 | - | |||||||
| 13 | - | |||||||
| 14 | - | |||||||
| 15 | - | |||||||
| 16 | - | |||||||
| 17 | - | |||||||
| 18 | - | |||||||
| 19 | - | |||||||
| 20 | static_assert(bool(sizeof(pthread_t) <= sizeof(Qt::HANDLE)), "sizeof(pthread_t) <= sizeof(Qt::HANDLE)"); | - | ||||||
| 21 | - | |||||||
| 22 | enum { ThreadPriorityResetFlag = 0x80000000 }; | - | ||||||
| 23 | static __thread QThreadData *currentThreadData = 0; | - | ||||||
| 24 | - | |||||||
| 25 | - | |||||||
| 26 | static pthread_once_t current_thread_data_once = 0; | - | ||||||
| 27 | static pthread_key_t current_thread_data_key; | - | ||||||
| 28 | - | |||||||
| 29 | static void destroy_current_thread_data(void *p) | - | ||||||
| 30 | { | - | ||||||
| 31 | pthread_setspecific(current_thread_data_key, p); | - | ||||||
| 32 | QThreadData *data = static_cast<QThreadData *>(p); | - | ||||||
| 33 | if (data->isAdopted) { | - | ||||||
| 34 | QThread *thread = data->thread; | - | ||||||
| 35 | ((!(thread)) ? qt_assert("thread",__FILE__,143148) : qt_noop()); | - | ||||||
| 36 | QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread)); | - | ||||||
| 37 | ((!(!thread_p->finished)) ? qt_assert("!thread_p->finished",__FILE__,145150) : qt_noop()); | - | ||||||
| 38 | thread_p->finish(thread); | - | ||||||
| 39 | } | - | ||||||
| 40 | data->deref(); | - | ||||||
| 41 | - | |||||||
| 42 | - | |||||||
| 43 | - | |||||||
| 44 | - | |||||||
| 45 | pthread_setspecific(current_thread_data_key, | - | ||||||
| 46 | - | |||||||
| 47 | - | |||||||
| 48 | - | |||||||
| 49 | 0); | - | ||||||
| 50 | - | |||||||
| 51 | } | - | ||||||
| 52 | - | |||||||
| 53 | static void create_current_thread_data_key() | - | ||||||
| 54 | { | - | ||||||
| 55 | pthread_key_create(¤t_thread_data_key, destroy_current_thread_data); | - | ||||||
| 56 | } | - | ||||||
| 57 | - | |||||||
| 58 | static void destroy_current_thread_data_key() | - | ||||||
| 59 | { | - | ||||||
| 60 | pthread_once(¤t_thread_data_once, create_current_thread_data_key); | - | ||||||
| 61 | pthread_key_delete(current_thread_data_key); | - | ||||||
| 62 | - | |||||||
| 63 | - | |||||||
| 64 | - | |||||||
| 65 | - | |||||||
| 66 | pthread_once_t pthread_once_init = 0; | - | ||||||
| 67 | current_thread_data_once = pthread_once_init; | - | ||||||
| 68 | } | - | ||||||
| 69 | namespace { static const struct destroy_current_thread_data_key_dtor_class_ { inline destroy_current_thread_data_key_dtor_class_() { } inline ~ destroy_current_thread_data_key_dtor_class_() { destroy_current_thread_data_key(); } } destroy_current_thread_data_key_dtor_instance_; } | - | ||||||
| 70 | - | |||||||
| 71 | - | |||||||
| 72 | - | |||||||
| 73 | static QThreadData *get_thread_data() | - | ||||||
| 74 | { | - | ||||||
| 75 | - | |||||||
| 76 | return currentThreadData; | - | ||||||
| 77 | - | |||||||
| 78 | - | |||||||
| 79 | - | |||||||
| 80 | - | |||||||
| 81 | } | - | ||||||
| 82 | - | |||||||
| 83 | static void set_thread_data(QThreadData *data) | - | ||||||
| 84 | { | - | ||||||
| 85 | - | |||||||
| 86 | currentThreadData = data; | - | ||||||
| 87 | - | |||||||
| 88 | pthread_once(¤t_thread_data_once, create_current_thread_data_key); | - | ||||||
| 89 | pthread_setspecific(current_thread_data_key, data); | - | ||||||
| 90 | } | - | ||||||
| 91 | - | |||||||
| 92 | static void clear_thread_data() | - | ||||||
| 93 | { | - | ||||||
| 94 | - | |||||||
| 95 | currentThreadData = 0; | - | ||||||
| 96 | - | |||||||
| 97 | pthread_setspecific(current_thread_data_key, 0); | - | ||||||
| 98 | } | - | ||||||
| 99 | - | |||||||
| 100 | template <typename T> | - | ||||||
| 101 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, Qt::HANDLE>::Type to_HANDLE(T id) | - | ||||||
| 102 | { | - | ||||||
| 103 | return reinterpret_cast<Qt::HANDLE>(static_cast<intptr_t>(id)); | - | ||||||
| 104 | } | - | ||||||
| 105 | - | |||||||
| 106 | template <typename T> | - | ||||||
| 107 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type from_HANDLE(Qt::HANDLE id) | - | ||||||
| 108 | { | - | ||||||
| 109 | return static_cast<T>(reinterpret_cast<intptr_t>(id)); | - | ||||||
| 110 | } | - | ||||||
| 111 | - | |||||||
| 112 | template <typename T> | - | ||||||
| 113 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, Qt::HANDLE>::Type to_HANDLE(T id) | - | ||||||
| 114 | { | - | ||||||
| 115 | return id; | - | ||||||
| 116 | } | - | ||||||
| 117 | - | |||||||
| 118 | template <typename T> | - | ||||||
| 119 | static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, T>::Type from_HANDLE(Qt::HANDLE id) | - | ||||||
| 120 | { | - | ||||||
| 121 | return static_cast<T>(id); | - | ||||||
| 122 | } | - | ||||||
| 123 | - | |||||||
| 124 | void QThreadData::clearCurrentThreadData() | - | ||||||
| 125 | { | - | ||||||
| 126 | clear_thread_data(); | - | ||||||
| 127 | } | - | ||||||
| 128 | - | |||||||
| 129 | QThreadData *QThreadData::current(bool createIfNecessary) | - | ||||||
| 130 | { | - | ||||||
| 131 | QThreadData *data = get_thread_data(); | - | ||||||
| 132 | if (!data && createIfNecessary) { | - | ||||||
| 133 | data = new QThreadData; | - | ||||||
| 134 | try { | - | ||||||
| 135 | set_thread_data(data); | - | ||||||
| 136 | data->thread = new QAdoptedThread(data); | - | ||||||
| 137 | } catch (...) { | - | ||||||
| 138 | clear_thread_data(); | - | ||||||
| 139 | data->deref(); | - | ||||||
| 140 | data = 0; | - | ||||||
| 141 | throw; | - | ||||||
| 142 | } | - | ||||||
| 143 | data->deref(); | - | ||||||
| 144 | data->isAdopted = true; | - | ||||||
| 145 | data->threadId = to_HANDLE(pthread_self()); | - | ||||||
| 146 | if (!QCoreApplicationPrivate::theMainThread) | - | ||||||
| 147 | QCoreApplicationPrivate::theMainThread = data->thread.load(); | - | ||||||
| 148 | } | - | ||||||
| 149 | return data; | - | ||||||
| 150 | } | - | ||||||
| 151 | - | |||||||
| 152 | - | |||||||
| 153 | void QAdoptedThread::init() | - | ||||||
| 154 | { | - | ||||||
| 155 | } | - | ||||||
| 156 | - | |||||||
| 157 | - | |||||||
| 158 | - | |||||||
| 159 | - | |||||||
| 160 | - | |||||||
| 161 | extern "C" { | - | ||||||
| 162 | typedef void*(*QtThreadCallback)(void*); | - | ||||||
| 163 | } | - | ||||||
| 164 | - | |||||||
| 165 | - | |||||||
| 166 | - | |||||||
| 167 | void QThreadPrivate::createEventDispatcher(QThreadData *data) | - | ||||||
| 168 | { | - | ||||||
| 169 |     if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
  | 0-620684 | ||||||
| 170 |         && qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
  | 0-620684 | ||||||
| 171 |         && QEventDispatcherGlib::versionSupported()
  | 0-620684 | ||||||
| 172 |         data->eventDispatcher.storeRelease(new QEventDispatcherGlib); executed 620684 times by 512 tests:  data->eventDispatcher.storeRelease(new QEventDispatcherGlib);Executed by: 
  | 620684 | ||||||
| 173 | else | - | ||||||
| 174 |         data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); never executed:  data->eventDispatcher.storeRelease(new QEventDispatcherUNIX); | 0 | ||||||
| 175 | - | |||||||
| 176 | - | |||||||
| 177 | - | |||||||
| 178 | - | |||||||
| 179 | data->eventDispatcher.load()->startingUp(); | - | ||||||
| 180 | } executed 620684 times by 512 tests:  end of blockExecuted by: 
  | 620684 | ||||||
| 181 | - | |||||||
| 182 | - | |||||||
| 183 | - | |||||||
| 184 | - | |||||||
| 185 | static void setCurrentThreadName(pthread_t threadId, const char *name) | - | ||||||
| 186 | { | - | ||||||
| 187 | - | |||||||
| 188 | (void)threadId;; | - | ||||||
| 189 | prctl(15, (unsigned long)name, 0, 0, 0); | - | ||||||
| 190 | - | |||||||
| 191 | - | |||||||
| 192 | - | |||||||
| 193 | - | |||||||
| 194 | - | |||||||
| 195 | - | |||||||
| 196 | } | - | ||||||
| 197 | - | |||||||
| 198 | - | |||||||
| 199 | void *QThreadPrivate::start(void *arg) | - | ||||||
| 200 | { | - | ||||||
| 201 | - | |||||||
| 202 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, __null); | - | ||||||
| 203 | - | |||||||
| 204 | do { __pthread_cleanup_class __clframe (QThreadPrivate::finish, arg); | - | ||||||
| 205 | - | |||||||
| 206 | QThread *thr = reinterpret_cast<QThread *>(arg); | - | ||||||
| 207 | QThreadData *data = QThreadData::get2(thr); | - | ||||||
| 208 | - | |||||||
| 209 | { | - | ||||||
| 210 | QMutexLocker locker(&thr->d_func()->mutex); | - | ||||||
| 211 | - | |||||||
| 212 | - | |||||||
| 213 | if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) { | - | ||||||
| 214 | thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); | - | ||||||
| 215 | } | - | ||||||
| 216 | - | |||||||
| 217 | data->threadId = to_HANDLE(pthread_self()); | - | ||||||
| 218 | set_thread_data(data); | - | ||||||
| 219 | - | |||||||
| 220 | data->ref(); | - | ||||||
| 221 | data->quitNow = thr->d_func()->exited; | - | ||||||
| 222 | } | - | ||||||
| 223 | - | |||||||
| 224 | if (data->eventDispatcher.load()) | - | ||||||
| 225 | data->eventDispatcher.load()->startingUp(); | - | ||||||
| 226 | else | - | ||||||
| 227 | createEventDispatcher(data); | - | ||||||
| 228 | - | |||||||
| 229 | - | |||||||
| 230 | { | - | ||||||
| 231 | - | |||||||
| 232 | QString objectName = thr->objectName(); | - | ||||||
| 233 | - | |||||||
| 234 | pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId); | - | ||||||
| 235 | if (__builtin_expect(!!(objectName.isEmpty()), true)) | - | ||||||
| 236 | setCurrentThreadName(thread_id, thr->metaObject()->className()); | - | ||||||
| 237 | else | - | ||||||
| 238 | setCurrentThreadName(thread_id, objectName.toLocal8Bit()); | - | ||||||
| 239 | } | - | ||||||
| 240 | - | |||||||
| 241 | - | |||||||
| 242 | thr->started(QThread::QPrivateSignal()); | - | ||||||
| 243 | - | |||||||
| 244 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, __null); | - | ||||||
| 245 | pthread_testcancel(); | - | ||||||
| 246 | - | |||||||
| 247 | thr->run(); | - | ||||||
| 248 | - | |||||||
| 249 | __clframe.__setdoit (1); } while (0); | - | ||||||
| 250 | - | |||||||
| 251 | return 0; | - | ||||||
| 252 | } | - | ||||||
| 253 | - | |||||||
| 254 | void QThreadPrivate::finish(void *arg) | - | ||||||
| 255 | { | - | ||||||
| 256 | QThread *thr = reinterpret_cast<QThread *>(arg); | - | ||||||
| 257 | QThreadPrivate *d = thr->d_func(); | - | ||||||
| 258 | - | |||||||
| 259 | QMutexLocker locker(&d->mutex); | - | ||||||
| 260 | - | |||||||
| 261 | d->isInFinish = true; | - | ||||||
| 262 | d->priority = QThread::InheritPriority; | - | ||||||
| 263 | void *data = &d->data->tls; | - | ||||||
| 264 | locker.unlock(); | - | ||||||
| 265 | thr->finished(QThread::QPrivateSignal()); | - | ||||||
| 266 | QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); | - | ||||||
| 267 | QThreadStorageData::finish((void **)data); | - | ||||||
| 268 | locker.relock(); | - | ||||||
| 269 | - | |||||||
| 270 | QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load(); | - | ||||||
| 271 | if (eventDispatcher) { | - | ||||||
| 272 | d->data->eventDispatcher = 0; | - | ||||||
| 273 | locker.unlock(); | - | ||||||
| 274 | eventDispatcher->closingDown(); | - | ||||||
| 275 | delete eventDispatcher; | - | ||||||
| 276 | locker.relock(); | - | ||||||
| 277 | } | - | ||||||
| 278 | - | |||||||
| 279 | d->running = false; | - | ||||||
| 280 | d->finished = true; | - | ||||||
| 281 | d->interruptionRequested = false; | - | ||||||
| 282 | - | |||||||
| 283 | d->isInFinish = false; | - | ||||||
| 284 | d->thread_done.wakeAll(); | - | ||||||
| 285 | } | - | ||||||
| 286 | Qt::HANDLE QThread::currentThreadId() noexcept | - | ||||||
| 287 | { | - | ||||||
| 288 | - | |||||||
| 289 |     return executed 13345982 times by 599 tests:   to_HANDLE(pthread_self());return to_HANDLE(pthread_self());Executed by: 
 executed 13345982 times by 599 tests:  return to_HANDLE(pthread_self());Executed by: 
  | 13345982 | ||||||
| 290 | } | - | ||||||
| 291 | - | |||||||
| 292 | - | |||||||
| 293 | - | |||||||
| 294 | - | |||||||
| 295 | - | |||||||
| 296 | - | |||||||
| 297 | int QThread::idealThreadCount() noexcept | - | ||||||
| 298 | { | - | ||||||
| 299 | int cores = 1; | - | ||||||
| 300 | cores = (int)sysconf(_SC_NPROCESSORS_ONLN); | - | ||||||
| 301 |     if (cores == -1
  | 0-1903 | ||||||
| 302 |         return never executed:   1;return 1;never executed:  return 1; | 0 | ||||||
| 303 | - | |||||||
| 304 |     return executed 1903 times by 447 tests:   cores;return cores;Executed by: 
 executed 1903 times by 447 tests:  return cores;Executed by: 
  | 1903 | ||||||
| 305 | } | - | ||||||
| 306 | - | |||||||
| 307 | void QThread::yieldCurrentThread() | - | ||||||
| 308 | { | - | ||||||
| 309 | sched_yield(); | - | ||||||
| 310 | } | - | ||||||
| 311 | - | |||||||
| 312 | static timespec makeTimespec(time_t secs, long nsecs) | - | ||||||
| 313 | { | - | ||||||
| 314 | struct timespec ts; | - | ||||||
| 315 | ts.tv_sec = secs; | - | ||||||
| 316 | ts.tv_nsec = nsecs; | - | ||||||
| 317 | return ts; | - | ||||||
| 318 | } | - | ||||||
| 319 | - | |||||||
| 320 | void QThread::sleep(unsigned long secs) | - | ||||||
| 321 | { | - | ||||||
| 322 | qt_nanosleep(makeTimespec(secs, 0)); | - | ||||||
| 323 | } | - | ||||||
| 324 | - | |||||||
| 325 | void QThread::msleep(unsigned long msecs) | - | ||||||
| 326 | { | - | ||||||
| 327 | qt_nanosleep(makeTimespec(msecs / 1000, msecs % 1000 * 1000 * 1000)); | - | ||||||
| 328 | } | - | ||||||
| 329 | - | |||||||
| 330 | void QThread::usleep(unsigned long usecs) | - | ||||||
| 331 | { | - | ||||||
| 332 | qt_nanosleep(makeTimespec(usecs / 1000 / 1000, usecs % (1000*1000) * 1000)); | - | ||||||
| 333 | } | - | ||||||
| 334 | - | |||||||
| 335 | - | |||||||
| 336 | - | |||||||
| 337 | - | |||||||
| 338 | - | |||||||
| 339 | static bool calculateUnixPriority(int priority, int *sched_policy, int *__sched_priority) | - | ||||||
| 340 | { | - | ||||||
| 341 | - | |||||||
| 342 | if (priority == QThread::IdlePriority) { | - | ||||||
| 343 | *sched_policy = 5; | - | ||||||
| 344 | *__sched_priority = 0; | - | ||||||
| 345 | return true; | - | ||||||
| 346 | } | - | ||||||
| 347 | const int lowestPriority = QThread::LowestPriority; | - | ||||||
| 348 | - | |||||||
| 349 | - | |||||||
| 350 | - | |||||||
| 351 | const int highestPriority = QThread::TimeCriticalPriority; | - | ||||||
| 352 | - | |||||||
| 353 | int prio_min; | - | ||||||
| 354 | int prio_max; | - | ||||||
| 355 | - | |||||||
| 356 | - | |||||||
| 357 | - | |||||||
| 358 | - | |||||||
| 359 | - | |||||||
| 360 | - | |||||||
| 361 | - | |||||||
| 362 | { | - | ||||||
| 363 | prio_min = sched_get_priority_min(*sched_policy); | - | ||||||
| 364 | prio_max = sched_get_priority_max(*sched_policy); | - | ||||||
| 365 | } | - | ||||||
| 366 | - | |||||||
| 367 | if (prio_min == -1 || prio_max == -1) | - | ||||||
| 368 | return false; | - | ||||||
| 369 | - | |||||||
| 370 | int prio; | - | ||||||
| 371 | - | |||||||
| 372 | prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min; | - | ||||||
| 373 | prio = qMax(prio_min, qMin(prio_max, prio)); | - | ||||||
| 374 | - | |||||||
| 375 | *__sched_priority = prio; | - | ||||||
| 376 | return true; | - | ||||||
| 377 | } | - | ||||||
| 378 | - | |||||||
| 379 | - | |||||||
| 380 | void QThread::start(Priority priority) | - | ||||||
| 381 | { | - | ||||||
| 382 | QThreadPrivate * const d = d_func(); | - | ||||||
| 383 | QMutexLocker locker(&d->mutex); | - | ||||||
| 384 | - | |||||||
| 385 | if (d->isInFinish) | - | ||||||
| 386 | d->thread_done.wait(locker.mutex()); | - | ||||||
| 387 | - | |||||||
| 388 | if (d->running) | - | ||||||
| 389 | return; | - | ||||||
| 390 | - | |||||||
| 391 | d->running = true; | - | ||||||
| 392 | d->finished = false; | - | ||||||
| 393 | d->returnCode = 0; | - | ||||||
| 394 | d->exited = false; | - | ||||||
| 395 | d->interruptionRequested = false; | - | ||||||
| 396 | - | |||||||
| 397 | pthread_attr_t attr; | - | ||||||
| 398 | pthread_attr_init(&attr); | - | ||||||
| 399 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | - | ||||||
| 400 | - | |||||||
| 401 | d->priority = priority; | - | ||||||
| 402 | - | |||||||
| 403 | - | |||||||
| 404 | switch (priority) { | - | ||||||
| 405 | case InheritPriority: | - | ||||||
| 406 | { | - | ||||||
| 407 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||
| 408 | break; | - | ||||||
| 409 | } | - | ||||||
| 410 | - | |||||||
| 411 | default: | - | ||||||
| 412 | { | - | ||||||
| 413 | int sched_policy; | - | ||||||
| 414 | if (pthread_attr_getschedpolicy(&attr, &sched_policy) != 0) { | - | ||||||
| 415 | - | |||||||
| 416 | - | |||||||
| 417 | QMessageLogger(__FILE__, 593596, __PRETTY_FUNCTION__).warning("QThread::start: Cannot determine default scheduler policy"); | - | ||||||
| 418 | break; | - | ||||||
| 419 | } | - | ||||||
| 420 | - | |||||||
| 421 | int prio; | - | ||||||
| 422 | if (!calculateUnixPriority(priority, &sched_policy, &prio)) { | - | ||||||
| 423 | - | |||||||
| 424 | - | |||||||
| 425 | QMessageLogger(__FILE__, 601604, __PRETTY_FUNCTION__).warning("QThread::start: Cannot determine scheduler priority range"); | - | ||||||
| 426 | break; | - | ||||||
| 427 | } | - | ||||||
| 428 | - | |||||||
| 429 | sched_param sp; | - | ||||||
| 430 | sp.__sched_priority = prio; | - | ||||||
| 431 | - | |||||||
| 432 | if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0 | - | ||||||
| 433 | || pthread_attr_setschedpolicy(&attr, sched_policy) != 0 | - | ||||||
| 434 | || pthread_attr_setschedparam(&attr, &sp) != 0) { | - | ||||||
| 435 | - | |||||||
| 436 | - | |||||||
| 437 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||
| 438 | d->priority = Priority(priority | ThreadPriorityResetFlag); | - | ||||||
| 439 | } | - | ||||||
| 440 | break; | - | ||||||
| 441 | } | - | ||||||
| 442 | } | - | ||||||
| 443 | - | |||||||
| 444 | - | |||||||
| 445 | - | |||||||
| 446 | if (d->stackSize > 0) { | - | ||||||
| 447 | - | |||||||
| 448 | int code = pthread_attr_setstacksize(&attr, d->stackSize); | - | ||||||
| 449 | - | |||||||
| 450 | - | |||||||
| 451 | - | |||||||
| 452 | - | |||||||
| 453 | if (code) { | - | ||||||
| 454 | QMessageLogger(__FILE__, 630633, __PRETTY_FUNCTION__).warning("QThread::start: Thread stack size error: %s", | - | ||||||
| 455 | QString(qt_error_string(code)).toLocal8Bit().constData()); | - | ||||||
| 456 | - | |||||||
| 457 | - | |||||||
| 458 | - | |||||||
| 459 | d->running = false; | - | ||||||
| 460 | d->finished = false; | - | ||||||
| 461 | return; | - | ||||||
| 462 | } | - | ||||||
| 463 | } | - | ||||||
| 464 | - | |||||||
| 465 | pthread_t threadId; | - | ||||||
| 466 | int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); | - | ||||||
| 467 | if (code == 1) { | - | ||||||
| 468 | - | |||||||
| 469 | - | |||||||
| 470 | - | |||||||
| 471 | pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); | - | ||||||
| 472 | - | |||||||
| 473 | code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); | - | ||||||
| 474 | } | - | ||||||
| 475 | d->data->threadId = to_HANDLE(threadId); | - | ||||||
| 476 | - | |||||||
| 477 | pthread_attr_destroy(&attr); | - | ||||||
| 478 | - | |||||||
| 479 | if (code) { | - | ||||||
| 480 | QMessageLogger(__FILE__, 656659, __PRETTY_FUNCTION__).warning("QThread::start: Thread creation error: %s", QString(qt_error_string(code)).toLocal8Bit().constData()); | - | ||||||
| 481 | - | |||||||
| 482 | d->running = false; | - | ||||||
| 483 | d->finished = false; | - | ||||||
| 484 | d->data->threadId = 0; | - | ||||||
| 485 | } | - | ||||||
| 486 | } | - | ||||||
| 487 | - | |||||||
| 488 | void QThread::terminate() | - | ||||||
| 489 | { | - | ||||||
| 490 | - | |||||||
| 491 | QThreadPrivate * const d = d_func(); | - | ||||||
| 492 | QMutexLocker locker(&d->mutex); | - | ||||||
| 493 | - | |||||||
| 494 | if (!d->data->threadId) | - | ||||||
| 495 | return; | - | ||||||
| 496 | - | |||||||
| 497 | int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId)); | - | ||||||
| 498 | if (code) { | - | ||||||
| 499 | QMessageLogger(__FILE__, 675678, __PRETTY_FUNCTION__).warning("QThread::start: Thread termination error: %s", | - | ||||||
| 500 | QString(qt_error_string((code))).toLocal8Bit().constData()); | - | ||||||
| 501 | } | - | ||||||
| 502 | - | |||||||
| 503 | } | - | ||||||
| 504 | - | |||||||
| 505 | bool QThread::wait(unsigned long time) | - | ||||||
| 506 | { | - | ||||||
| 507 | QThreadPrivate * const d = d_func(); | - | ||||||
| 508 | QMutexLocker locker(&d->mutex); | - | ||||||
| 509 | - | |||||||
| 510 | if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) { | - | ||||||
| 511 | QMessageLogger(__FILE__, 687690, __PRETTY_FUNCTION__).warning("QThread::wait: Thread tried to wait on itself"); | - | ||||||
| 512 | return false; | - | ||||||
| 513 | } | - | ||||||
| 514 | - | |||||||
| 515 | if (d->finished || !d->running) | - | ||||||
| 516 | return true; | - | ||||||
| 517 | - | |||||||
| 518 | while (d->running) { | - | ||||||
| 519 | if (!d->thread_done.wait(locker.mutex(), time)) | - | ||||||
| 520 | return false; | - | ||||||
| 521 | } | - | ||||||
| 522 | return true; | - | ||||||
| 523 | } | - | ||||||
| 524 | - | |||||||
| 525 | void QThread::setTerminationEnabled(bool enabled) | - | ||||||
| 526 | { | - | ||||||
| 527 | QThread *thr = currentThread(); | - | ||||||
| 528 | ((!(thr != 0)) ? qt_assert_x("QThread::setTerminationEnabled()", "Current thread was not started with QThread.", | - | ||||||
| 529 | __FILE__ | - | ||||||
| 530 | , | - | ||||||
| 531 | 705708 | - | ||||||
| 532 | ) : qt_noop()) | - | ||||||
| 533 | ; | - | ||||||
| 534 | - | |||||||
| 535 | (void)thr; | - | ||||||
| 536 | - | |||||||
| 537 | - | |||||||
| 538 | - | |||||||
| 539 | pthread_setcancelstate(enabled ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE, __null); | - | ||||||
| 540 | if (enabled) | - | ||||||
| 541 | pthread_testcancel(); | - | ||||||
| 542 | - | |||||||
| 543 | } | - | ||||||
| 544 | - | |||||||
| 545 | - | |||||||
| 546 | void QThreadPrivate::setPriority(QThread::Priority threadPriority) | - | ||||||
| 547 | { | - | ||||||
| 548 | priority = threadPriority; | - | ||||||
| 549 | - | |||||||
| 550 | - | |||||||
| 551 | - | |||||||
| 552 | - | |||||||
| 553 | int sched_policy; | - | ||||||
| 554 | sched_param param; | - | ||||||
| 555 | - | |||||||
| 556 | if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m) != 0) { | - | ||||||
| 557 | - | |||||||
| 558 | - | |||||||
| 559 | QMessageLogger(__FILE__, 731734, __PRETTY_FUNCTION__).warning("QThread::setPriority: Cannot get scheduler parameters"); | - | ||||||
| 560 | return; | - | ||||||
| 561 | } | - | ||||||
| 562 | - | |||||||
| 563 | int prio; | - | ||||||
| 564 | if (!calculateUnixPriority(priority, &sched_policy, &prio)) { | - | ||||||
| 565 | - | |||||||
| 566 | - | |||||||
| 567 | QMessageLogger(__FILE__, 739742, __PRETTY_FUNCTION__).warning("QThread::setPriority: Cannot determine scheduler priority range"); | - | ||||||
| 568 | return; | - | ||||||
| 569 | } | - | ||||||
| 570 | - | |||||||
| 571 | param.__sched_priority = prio; | - | ||||||
| 572 | int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); | - | ||||||
| 573 | - | |||||||
| 574 | - | |||||||
| 575 | - | |||||||
| 576 | if (status == -1 && sched_policy == 5 && (*__errno_location ()) == 22) { | - | ||||||
| 577 | - | |||||||
| 578 | pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m); | - | ||||||
| 579 | param.__sched_priority = sched_get_priority_min(sched_policy); | - | ||||||
| 580 | pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); | - | ||||||
| 581 | } | - | ||||||
| 582 | - | |||||||
| 583 | - | |||||||
| 584 | - | |||||||
| 585 | - | |||||||
| 586 | } | - | ||||||
| 587 | - | |||||||
| 588 | - | |||||||
| 589 | - | |||||||
| 590 | - | |||||||
| Switch to Source code | Preprocessed file |