void *QThreadPrivate::start(void *arg) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_cleanup_push(QThreadPrivate::finish, arg); QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); pthread_once(¤t_thread_data_once, create_current_thread_data_key); pthread_setspecific(current_thread_data_key, data); data->ref(); data->quitNow = false; // ### TODO: allow the user to create a custom event dispatcher createEventDispatcher(data); emit thr->started(); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); thr->run(); pthread_cleanup_pop(1); return 0; }
void QObject::moveToThread(QThread *targetThread) { if (m_threadData.load()->thread == targetThread) { // object is already in this thread return; } if (m_parent != 0) { qWarning("QObject::moveToThread() Can not move an object with a parent"); return; } if (isWidgetType()) { qWarning("QObject::moveToThread() Widgets can not be moved to a new thread"); return; } QThreadData *currentData = QThreadData::current(); QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0); QThreadData *threadData = m_threadData.load(); if (threadData->thread == 0 && currentData == targetData) { // exception: allow moving objects with no thread affinity to the current thread currentData = threadData; } else if (threadData != currentData) { qWarning("QObject::moveToThread() Current thread (%p) is not the current object's thread (%p).\n" "Can not move to target thread (%p)\n", currentData->thread, threadData->thread, targetData->thread); #ifdef Q_WS_MAC qWarning("Multiple libraries might be loaded in the same process. Verify all plugins are " "linked with the correct binaries. Export DYLD_PRINT_LIBRARIES=1 and verify only one set of " "binaries are being loaded."); #endif return; } // prepare to move this->moveToThread_helper(); QOrderedMutexLocker locker(¤tData->postEventList.mutex, &targetData->postEventList.mutex); // keep currentData alive currentData->ref(); // move the object this->setThreadData_helper(currentData, targetData); locker.unlock(); currentData->deref(); }