diff options
Diffstat (limited to 'src/corelib/thread/qthread_unix.cpp')
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index a7601b654a..f508c0a4c0 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -83,7 +83,9 @@ # define old_qDebug qDebug # undef qDebug # endif +#ifndef QT_NO_CORESERVICES # include <CoreServices/CoreServices.h> +#endif //QT_NO_CORESERVICES # ifdef old_qDebug # undef qDebug @@ -142,6 +144,39 @@ static void destroy_current_thread_data_key() } Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key) + +// Utility functions for getting, setting and clearing thread specific data. +// In Symbian, TLS access is significantly faster than pthread_getspecific. +// However Symbian does not have the thread destruction cleanup functionality +// that pthread has, so pthread_setspecific is also used. +static QThreadData *get_thread_data() +{ +#ifdef Q_OS_SYMBIAN + return reinterpret_cast<QThreadData *>(Dll::Tls()); +#else + pthread_once(¤t_thread_data_once, create_current_thread_data_key); + return reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); +#endif +} + +static void set_thread_data(QThreadData *data) +{ +#ifdef Q_OS_SYMBIAN + qt_symbian_throwIfError(Dll::SetTls(data)); +#endif + pthread_once(¤t_thread_data_once, create_current_thread_data_key); + pthread_setspecific(current_thread_data_key, data); +} + +static void clear_thread_data() +{ +#ifdef Q_OS_SYMBIAN + Dll::FreeTls(); +#endif + pthread_setspecific(current_thread_data_key, 0); +} + + #ifdef Q_OS_SYMBIAN static void init_symbian_thread_handle(RThread &thread) { @@ -158,26 +193,24 @@ static void init_symbian_thread_handle(RThread &thread) QThreadData *QThreadData::current() { - pthread_once(¤t_thread_data_once, create_current_thread_data_key); - - QThreadData *data = reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); + QThreadData *data = get_thread_data(); if (!data) { void *a; if (QInternal::activateCallbacks(QInternal::AdoptCurrentThread, &a)) { QThread *adopted = static_cast<QThread*>(a); Q_ASSERT(adopted); data = QThreadData::get2(adopted); - pthread_setspecific(current_thread_data_key, data); + set_thread_data(data); adopted->d_func()->running = true; adopted->d_func()->finished = false; static_cast<QAdoptedThread *>(adopted)->init(); } else { data = new QThreadData; - pthread_setspecific(current_thread_data_key, data); QT_TRY { + set_thread_data(data); data->thread = new QAdoptedThread(data); } QT_CATCH(...) { - pthread_setspecific(current_thread_data_key, 0); + clear_thread_data(); data->deref(); data = 0; QT_RETHROW; @@ -268,8 +301,7 @@ void *QThreadPrivate::start(void *arg) User::SetCritical(User::EProcessCritical); #endif - pthread_once(¤t_thread_data_once, create_current_thread_data_key); - pthread_setspecific(current_thread_data_key, data); + set_thread_data(data); data->ref(); data->quitNow = false; @@ -313,6 +345,7 @@ void QThreadPrivate::finish(void *arg) emit thr->terminated(); d->terminated = false; emit thr->finished(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); if (d->data->eventDispatcher) { d->data->eventDispatcher->closingDown(); @@ -358,7 +391,7 @@ int QThread::idealThreadCount() { int cores = -1; -#if defined(Q_OS_MAC) +#if defined(Q_OS_MAC) && !defined(Q_WS_QPA) // Mac OS X cores = MPProcessorsScheduled(); #elif defined(Q_OS_HPUX) @@ -476,6 +509,7 @@ void QThread::usleep(unsigned long usecs) // Does some magic and calculate the Unix scheduler priorities // sched_policy is IN/OUT: it must be set to a valid policy before calling this function // sched_priority is OUT only +#if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority) { #ifdef SCHED_IDLE @@ -503,6 +537,7 @@ static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_pr *sched_priority = prio; return true; } +#endif void QThread::start(Priority priority) { |