From e969e6d2ca5636b87b3de963ebd8dac993275617 Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Thu, 9 Jun 2016 12:13:08 -0400 Subject: Fix cast warnings when pthread_t is smaller than a pointer Push conversions from pthread_t to Qt::HANDLE and back into functions. The casts that were being used didn't work for the unusual 64-bit pointer/32-bit int combination that QNX is using for 7.0. HANDLE ends up as a 64-bit pointer and pthread_t ends up as a 32-bit integer. g++ considers the precision loss when converting from the 64-bit pointer to the 32-bit integer an error. Better to have the casts hidden in functions so it's easier to adjust them for unusual combinations such as this. Change-Id: Ia156b26224a0f7edc1c31e3d1ee8b21191381698 Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread_unix.cpp | 55 ++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'src/corelib/thread') diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 3fc0ebfbb6..8c35d49aa3 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD -Q_STATIC_ASSERT(sizeof(pthread_t) == sizeof(Qt::HANDLE)); +Q_STATIC_ASSERT(sizeof(pthread_t) <= sizeof(Qt::HANDLE)); enum { ThreadPriorityResetFlag = 0x80000000 }; @@ -205,6 +205,30 @@ static void clear_thread_data() pthread_setspecific(current_thread_data_key, 0); } +template +static typename QtPrivate::QEnableIf::isIntegral, Qt::HANDLE>::Type to_HANDLE(T id) +{ + return reinterpret_cast(static_cast(id)); +} + +template +static typename QtPrivate::QEnableIf::isIntegral, T>::Type from_HANDLE(Qt::HANDLE id) +{ + return static_cast(reinterpret_cast(id)); +} + +template +static typename QtPrivate::QEnableIf::isPointer, Qt::HANDLE>::Type to_HANDLE(T id) +{ + return id; +} + +template +static typename QtPrivate::QEnableIf::isPointer, T>::Type from_HANDLE(Qt::HANDLE id) +{ + return static_cast(id); +} + void QThreadData::clearCurrentThreadData() { clear_thread_data(); @@ -226,7 +250,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) } data->deref(); data->isAdopted = true; - data->threadId = (Qt::HANDLE)pthread_self(); + data->threadId = to_HANDLE(pthread_self()); if (!QCoreApplicationPrivate::theMainThread) QCoreApplicationPrivate::theMainThread = data->thread.load(); } @@ -308,7 +332,7 @@ void *QThreadPrivate::start(void *arg) thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); } - data->threadId = (Qt::HANDLE)pthread_self(); + data->threadId = to_HANDLE(pthread_self()); set_thread_data(data); data->ref(); @@ -325,7 +349,7 @@ void *QThreadPrivate::start(void *arg) // sets the name of the current thread. QString objectName = thr->objectName(); - pthread_t thread_id = reinterpret_cast(data->threadId); + pthread_t thread_id = from_HANDLE(data->threadId); if (Q_LIKELY(objectName.isEmpty())) setCurrentThreadName(thread_id, thr->metaObject()->className()); else @@ -388,7 +412,7 @@ void QThreadPrivate::finish(void *arg) Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW { // requires a C cast here otherwise we run into trouble on AIX - return (Qt::HANDLE)pthread_self(); + return to_HANDLE(pthread_self()); } #if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN) @@ -614,18 +638,17 @@ void QThread::start(Priority priority) } } - int code = - pthread_create(reinterpret_cast(&d->data->threadId), &attr, - QThreadPrivate::start, this); + pthread_t threadId; + int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); if (code == EPERM) { // caller does not have permission to set the scheduling // parameters/policy #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); #endif - code = pthread_create(reinterpret_cast(&d->data->threadId), &attr, - QThreadPrivate::start, this); + code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); } + d->data->threadId = to_HANDLE(threadId); pthread_attr_destroy(&attr); @@ -647,7 +670,7 @@ void QThread::terminate() if (!d->data->threadId) return; - int code = pthread_cancel(reinterpret_cast(d->data->threadId)); + int code = pthread_cancel(from_HANDLE(d->data->threadId)); if (code) { qWarning("QThread::start: Thread termination error: %s", qPrintable(qt_error_string((code)))); @@ -660,7 +683,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); - if (reinterpret_cast(d->data->threadId) == pthread_self()) { + if (from_HANDLE(d->data->threadId) == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -702,7 +725,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int sched_policy; sched_param param; - if (pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m) != 0) { + if (pthread_getschedparam(from_HANDLE(data->threadId), &sched_policy, ¶m) != 0) { // failed to get the scheduling policy, don't bother setting // the priority qWarning("QThread::setPriority: Cannot get scheduler parameters"); @@ -718,15 +741,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) } param.sched_priority = prio; - int status = pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); + int status = pthread_setschedparam(from_HANDLE(data->threadId), sched_policy, ¶m); # ifdef SCHED_IDLE // were we trying to set to idle priority and failed? if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { // reset to lowest priority possible - pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m); + pthread_getschedparam(from_HANDLE(data->threadId), &sched_policy, ¶m); param.sched_priority = sched_get_priority_min(sched_policy); - pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); + pthread_setschedparam(from_HANDLE(data->threadId), sched_policy, ¶m); } # else Q_UNUSED(status); -- cgit v1.2.3