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 <thiago.macieira@intel.com>
This commit is contained in:
James McDonnell 2016-06-09 12:13:08 -04:00
parent 27e94bd9d1
commit e969e6d2ca

View File

@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD #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 }; enum { ThreadPriorityResetFlag = 0x80000000 };
@ -205,6 +205,30 @@ static void clear_thread_data()
pthread_setspecific(current_thread_data_key, 0); pthread_setspecific(current_thread_data_key, 0);
} }
template <typename T>
static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, Qt::HANDLE>::Type to_HANDLE(T id)
{
return reinterpret_cast<Qt::HANDLE>(static_cast<intptr_t>(id));
}
template <typename T>
static typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type from_HANDLE(Qt::HANDLE id)
{
return static_cast<T>(reinterpret_cast<intptr_t>(id));
}
template <typename T>
static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, Qt::HANDLE>::Type to_HANDLE(T id)
{
return id;
}
template <typename T>
static typename QtPrivate::QEnableIf<QTypeInfo<T>::isPointer, T>::Type from_HANDLE(Qt::HANDLE id)
{
return static_cast<T>(id);
}
void QThreadData::clearCurrentThreadData() void QThreadData::clearCurrentThreadData()
{ {
clear_thread_data(); clear_thread_data();
@ -226,7 +250,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
} }
data->deref(); data->deref();
data->isAdopted = true; data->isAdopted = true;
data->threadId = (Qt::HANDLE)pthread_self(); data->threadId = to_HANDLE(pthread_self());
if (!QCoreApplicationPrivate::theMainThread) if (!QCoreApplicationPrivate::theMainThread)
QCoreApplicationPrivate::theMainThread = data->thread.load(); 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)); 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); set_thread_data(data);
data->ref(); data->ref();
@ -325,7 +349,7 @@ void *QThreadPrivate::start(void *arg)
// sets the name of the current thread. // sets the name of the current thread.
QString objectName = thr->objectName(); QString objectName = thr->objectName();
pthread_t thread_id = reinterpret_cast<pthread_t>(data->threadId); pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId);
if (Q_LIKELY(objectName.isEmpty())) if (Q_LIKELY(objectName.isEmpty()))
setCurrentThreadName(thread_id, thr->metaObject()->className()); setCurrentThreadName(thread_id, thr->metaObject()->className());
else else
@ -388,7 +412,7 @@ void QThreadPrivate::finish(void *arg)
Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
{ {
// requires a C cast here otherwise we run into trouble on AIX // 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) #if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)
@ -614,18 +638,17 @@ void QThread::start(Priority priority)
} }
} }
int code = pthread_t threadId;
pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr, int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
QThreadPrivate::start, this);
if (code == EPERM) { if (code == EPERM) {
// caller does not have permission to set the scheduling // caller does not have permission to set the scheduling
// parameters/policy // parameters/policy
#if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING)
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
#endif #endif
code = pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr, code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
QThreadPrivate::start, this);
} }
d->data->threadId = to_HANDLE(threadId);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
@ -647,7 +670,7 @@ void QThread::terminate()
if (!d->data->threadId) if (!d->data->threadId)
return; return;
int code = pthread_cancel(reinterpret_cast<pthread_t>(d->data->threadId)); int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId));
if (code) { if (code) {
qWarning("QThread::start: Thread termination error: %s", qWarning("QThread::start: Thread termination error: %s",
qPrintable(qt_error_string((code)))); qPrintable(qt_error_string((code))));
@ -660,7 +683,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread); Q_D(QThread);
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
if (reinterpret_cast<pthread_t>(d->data->threadId) == pthread_self()) { if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself"); qWarning("QThread::wait: Thread tried to wait on itself");
return false; return false;
} }
@ -702,7 +725,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy; int sched_policy;
sched_param param; sched_param param;
if (pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param) != 0) { if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting // failed to get the scheduling policy, don't bother setting
// the priority // the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters"); qWarning("QThread::setPriority: Cannot get scheduler parameters");
@ -718,15 +741,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
} }
param.sched_priority = prio; param.sched_priority = prio;
int status = pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param); int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, &param);
# ifdef SCHED_IDLE # ifdef SCHED_IDLE
// were we trying to set to idle priority and failed? // were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible // reset to lowest priority possible
pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param); pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy); param.sched_priority = sched_get_priority_min(sched_policy);
pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param); pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, &param);
} }
# else # else
Q_UNUSED(status); Q_UNUSED(status);