Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/corelib/thread/qthread_unix.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation ([email protected])
     
    9393#endif
    9494
     95
     96
     97
     98
     99
     100
     101
     102
     103
     104
    95105QT_BEGIN_NAMESPACE
    96106
    97107#ifndef QT_NO_THREAD
     108
     109
    98110
    99111static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT;
     
    130142}
    131143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
    132197QThreadData *QThreadData::current()
    133198{
    134     pthread_once(&current_thread_data_once, create_current_thread_data_key);
    135 
    136     QThreadData *data = reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
     199    QThreadData *data = get_thread_data();
    137200    if (!data) {
    138201        void *a;
     
    141204            Q_ASSERT(adopted);
    142205            data = QThreadData::get2(adopted);
    143             pthread_setspecific(current_thread_data_key, data);
     206            data);
    144207            adopted->d_func()->running = true;
    145208            adopted->d_func()->finished = false;
     
    147210        } else {
    148211            data = new QThreadData;
    149             pthread_setspecific(current_thread_data_key, data);
    150212            QT_TRY {
     213
    151214                data->thread = new QAdoptedThread(data);
    152215            } QT_CATCH(...) {
    153                 pthread_setspecific(current_thread_data_key, 0);
     216                );
    154217                data->deref();
    155218                data = 0;
     
    170233    d->thread_id = pthread_self();
    171234#ifdef Q_OS_SYMBIAN
    172     d->data->symbian_thread_handle = RThread();
    173     TThreadId threadId = d->data->symbian_thread_handle.Id();
    174     d->data->symbian_thread_handle.Open(threadId);
     235    init_symbian_thread_handle(d->data->symbian_thread_handle);
    175236#endif
    176237}
     
    222283    QThreadData *data = QThreadData::get2(thr);
    223284
     285
     286
     287
     288
     289
    224290#ifdef Q_OS_SYMBIAN
    225291    // Because Symbian Open C does not provide a way to convert between
     
    227293    // handle when creating a thread, until we are running in the new thread.
    228294    // Here, we pick up the current thread and assign that to the handle.
    229     data->symbian_thread_handle = RThread();
    230     TThreadId threadId = data->symbian_thread_handle.Id();
    231     data->symbian_thread_handle.Open(threadId);
    232 #endif
    233 
    234     pthread_once(&current_thread_data_once, create_current_thread_data_key);
    235     pthread_setspecific(current_thread_data_key, data);
     295    init_symbian_thread_handle(data->symbian_thread_handle);
     296
     297    // On symbian, threads other than the main thread are non critical by default
     298    // This means a worker thread can crash without crashing the application - to
     299    // use this feature, we would need to use RThread::Logon in the main thread
     300    // to catch abnormal thread exit and emit the finished signal.
     301    // For the sake of cross platform consistency, we set the thread as process critical
     302    // - advanced users who want the symbian behaviour can change the critical
     303    // attribute of the thread again once the app gains control in run()
     304    User::SetCritical(User::EProcessCritical);
     305#endif
     306
     307    set_thread_data(data);
    236308
    237309    data->ref();
     
    437509}
    438510
     511
     512
     513
     514
     515
     516
     517
     518
     519
     520
     521
     522
     523
     524
     525
     526
     527
     528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
    439544void QThread::start(Priority priority)
    440545{
     
    447552    d->finished = false;
    448553    d->terminated = false;
     554
     555
    449556
    450557    pthread_attr_t attr;
     
    454561    d->priority = priority;
    455562
    456 #if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && !defined(Q_OS_SYMBIAN) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0)
     563#if defined(Q)
    457564// ### Need to implement thread sheduling and priorities for symbian os. Implementation removed for now
    458565    switch (priority) {
     
    473580            }
    474581
    475             int prio_min = sched_get_priority_min(sched_policy);
    476             int prio_max = sched_get_priority_max(sched_policy);
    477             if (prio_min == -1 || prio_max == -1) {
     582            int prio;
     583            if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
    478584                // failed to get the scheduling parameters, don't
    479585                // bother setting the priority
     
    482588            }
    483589
    484             int prio;
    485             switch (priority) {
    486             case IdlePriority:
    487                 prio = prio_min;
    488                 break;
    489 
    490             case TimeCriticalPriority:
    491                 prio = prio_max;
    492                 break;
    493 
    494             default:
    495                 // crudely scale our priority enum values to the prio_min/prio_max
    496                 prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min;
    497                 prio = qMax(prio_min, qMin(prio_max, prio));
    498                 break;
    499             }
    500 
    501590            sched_param sp;
    502591            sp.sched_priority = prio;
     
    506595                || pthread_attr_setschedparam(&attr, &sp) != 0) {
    507596                // could not set scheduling hints, fallback to inheriting them
     597
    508598                pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
     599
    509600            }
    510601            break;
    511602        }
    512603    }
    513 #endif // _POSIX_THREAD_PRIORITY_SCHEDULING
     604#endif // _THREAD_PRIORITY_SCHEDULING
    514605
    515606#ifdef Q_OS_SYMBIAN
     
    617708
    618709    while (d->running) {
     710
     711
     712
     713
     714
     715
     716
     717
     718
     719
     720
     721
    619722        if (!d->thread_done.wait(locker.mutex(), time))
    620723            return false;
     
    662765    // copied from start() with a few modifications:
    663766
    664 #if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0)
     767#if
    665768    int sched_policy;
    666769    sched_param param;
     
    673776    }
    674777
    675     int prio_min = sched_get_priority_min(sched_policy);
    676     int prio_max = sched_get_priority_max(sched_policy);
    677     if (prio_min == -1 || prio_max == -1) {
     778    int prio;
     779    if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
    678780        // failed to get the scheduling parameters, don't
    679781        // bother setting the priority
     
    682784    }
    683785
    684     int prio;
    685     switch (priority) {
    686     case InheritPriority:
    687         qWarning("QThread::setPriority: Argument cannot be InheritPriority");
    688         return;
    689 
    690     case IdlePriority:
    691         prio = prio_min;
    692         break;
    693 
    694     case TimeCriticalPriority:
    695         prio = prio_max;
    696         break;
    697 
    698     default:
    699         // crudely scale our priority enum values to the prio_min/prio_max
    700         prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min;
    701         prio = qMax(prio_min, qMin(prio_max, prio));
    702         break;
    703     }
    704 
    705786    param.sched_priority = prio;
    706     pthread_setschedparam(d->thread_id, sched_policy, &param);
     787    int status = pthread_setschedparam(d->thread_id, sched_policy, &param);
     788
     789# ifdef SCHED_IDLE
     790    // were we trying to set to idle priority and failed?
     791    if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
     792        // reset to lowest priority possible
     793        pthread_getschedparam(d->thread_id, &sched_policy, &param);
     794        param.sched_priority = sched_get_priority_min(sched_policy);
     795        pthread_setschedparam(d->thread_id, sched_policy, &param);
     796    }
     797# else
     798    Q_UNUSED(status);
     799# endif // SCHED_IDLE
    707800#endif
    708801}
Note: See TracChangeset for help on using the changeset viewer.