Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/corelib/kernel/qeventdispatcher_unix.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtCore module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5050#include <private/qthread_p.h>
    5151#include <private/qcoreapplication_p.h>
     52
    5253
    5354#include <errno.h>
     
    5556#include <stdlib.h>
    5657
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
    5768#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
    5869#  include <sys/times.h>
     
    7788
    7889
     90
    7991static void initThreadPipeFD(int fd)
    8092{
     
    91103        perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe");
    92104}
    93 
     105#endif
    94106
    95107QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
     
    97109    extern Qt::HANDLE qt_application_thread_id;
    98110    mainThread = (QThread::currentThreadId() == qt_application_thread_id);
     111
    99112
    100113    // initialize the common parts of the event loop
    101 #ifdef Q_OS_INTEGRITY
     114#if
    102115    // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
    103     if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1)
     116    if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1)
    104117        perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
    105142#else
    106     if (pipe(thread_pipe) == -1)
     143    if (
    107144        perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
    108 #endif
    109 
    110     initThreadPipeFD(thread_pipe[0]);
    111     initThreadPipeFD(thread_pipe[1]);
     145        pipefail = true;
     146    }
     147#endif
     148
     149    if (pipefail)
     150        qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
    112151
    113152    sn_highest = -1;
     
    118157QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
    119158{
     159
     160
     161
     162
     163
     164
     165
     166
    120167    // cleanup the common parts of the event loop
    121168    close(thread_pipe[0]);
    122169    close(thread_pipe[1]);
     170
    123171
    124172    // cleanup timers
     
    185233
    186234                for (int i = 0; i < list.size(); ++i) {
    187                     QSockNot *sn = list.at(i);
     235                    QSockNot *sn = list;
    188236
    189237                    FD_ZERO(&fdset);
     
    225273    int nevents = 0;
    226274    if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) {
     275
     276
     277
     278
     279
    227280        char c[16];
    228281        while (::read(thread_pipe[0], c, sizeof(c)) > 0)
    229282            ;
     283
    230284        if (!wakeUps.testAndSetRelease(1, 0)) {
    231285            // hopefully, this is dead code
     
    242296            QSockNotType::List &list = sn_vec[i].list;
    243297            for (int j = 0; j < list.size(); ++j) {
    244                 QSockNot *sn = list.at(j);
     298                QSockNot *sn = list;
    245299                if (FD_ISSET(sn->fd, &sn_vec[i].select_fds))
    246300                    q->setSocketNotifierPending(sn->obj);
     
    258312QTimerInfoList::QTimerInfoList()
    259313{
    260 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0)
    261     useMonotonicTimers = false;
    262 
    263 #  if (_POSIX_MONOTONIC_CLOCK == 0)
    264     // detect if the system support monotonic timers
    265     long x = sysconf(_SC_MONOTONIC_CLOCK);
    266     useMonotonicTimers = x >= 200112L;
    267 #  endif
    268 
    269     getTime(currentTime);
    270 
    271     if (!useMonotonicTimers) {
     314    currentTime = qt_gettime();
     315
     316#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)
     317    if (!qt_gettime_is_monotonic()) {
    272318        // not using monotonic timers, initialize the timeChanged() machinery
    273319        previousTime = currentTime;
     
    285331        msPerTick = 0;
    286332    }
    287 #else
    288     // using monotonic timers unconditionally
    289     getTime(currentTime);
    290333#endif
    291334
     
    295338timeval QTimerInfoList::updateCurrentTime()
    296339{
    297     getTime(currentTime);
    298     return currentTime;
    299 }
    300 
    301 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
     340    return (currentTime = qt_gettime());
     341}
     342
     343#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED)
     344
     345template <>
     346timeval qAbs(const timeval &t)
     347{
     348    timeval tmp = t;
     349    if (tmp.tv_sec < 0) {
     350        tmp.tv_sec = -tmp.tv_sec - 1;
     351        tmp.tv_usec -= 1000000;
     352    }
     353    if (tmp.tv_sec == 0 && tmp.tv_usec < 0) {
     354        tmp.tv_usec = -tmp.tv_usec;
     355    }
     356    return normalizedTimeval(tmp);
     357}
    302358
    303359/*
     
    310366bool QTimerInfoList::timeChanged(timeval *delta)
    311367{
    312     tms unused;
     368    tms unused;
    313369    clock_t currentTicks = times(&unused);
    314370
    315     int elapsedTicks = currentTicks - previousTicks;
     371    t elapsedTicks = currentTicks - previousTicks;
    316372    timeval elapsedTime = currentTime - previousTime;
    317     int elapsedMsecTicks = (elapsedTicks * 1000) / ticksPerSecond;
    318     int deltaMsecs = (elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000)
    319                      - elapsedMsecTicks;
    320 
    321     if (delta) {
    322         delta->tv_sec = deltaMsecs / 1000;
    323         delta->tv_usec = (deltaMsecs % 1000) * 1000;
    324     }
     373
     374    timeval elapsedTimeTicks;
     375    elapsedTimeTicks.tv_sec = elapsedTicks / ticksPerSecond;
     376    elapsedTimeTicks.tv_usec = (((elapsedTicks * 1000) / ticksPerSecond) % 1000) * 1000;
     377
     378    timeval dummy;
     379    if (!delta)
     380        delta = &dummy;
     381    *delta = elapsedTime - elapsedTimeTicks;
     382
    325383    previousTicks = currentTicks;
    326384    previousTime = currentTime;
     
    328386    // If tick drift is more than 10% off compared to realtime, we assume that the clock has
    329387    // been set. Of course, we have to allow for the tick granularity as well.
    330 
    331      return (qAbs(deltaMsecs) - msPerTick) * 10 > elapsedMsecTicks;
    332 }
    333 
    334 void QTimerInfoList::getTime(timeval &t)
    335 {
    336 #if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
    337     if (useMonotonicTimers) {
    338         timespec ts;
    339         clock_gettime(CLOCK_MONOTONIC, &ts);
    340         t.tv_sec = ts.tv_sec;
    341         t.tv_usec = ts.tv_nsec / 1000;
    342         return;
    343     }
    344 #endif
    345 
    346     gettimeofday(&t, 0);
    347     // NTP-related fix
    348     while (t.tv_usec >= 1000000l) {
    349         t.tv_usec -= 1000000l;
    350         ++t.tv_sec;
    351     }
    352     while (t.tv_usec < 0l) {
    353         if (t.tv_sec > 0l) {
    354             t.tv_usec += 1000000l;
    355             --t.tv_sec;
    356         } else {
    357             t.tv_usec = 0l;
    358             break;
    359         }
    360     }
     388    timeval tickGranularity;
     389    tickGranularity.tv_sec = 0;
     390    tickGranularity.tv_usec = msPerTick * 1000;
     391    return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10);
    361392}
    362393
    363394void QTimerInfoList::repairTimersIfNeeded()
    364395{
    365     if (useMonotonicTimers)
     396    if ()
    366397        return;
    367398    timeval delta;
     
    371402
    372403#else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED)
    373 
    374 void QTimerInfoList::getTime(timeval &t)
    375 {
    376     timespec ts;
    377     clock_gettime(CLOCK_MONOTONIC, &ts);
    378     t.tv_sec = ts.tv_sec;
    379     t.tv_usec = ts.tv_nsec / 1000;
    380 }
    381404
    382405void QTimerInfoList::repairTimersIfNeeded()
     
    408431    for (int i = 0; i < size(); ++i) {
    409432        register QTimerInfo *t = at(i);
    410         t->timeout = t->timeout - diff;
     433        t->timeout = t->timeout diff;
    411434    }
    412435}
     
    421444    repairTimersIfNeeded();
    422445
    423     if (isEmpty())
    424         return false;
    425 
    426     QTimerInfo *t = first();        // first waiting timer
     446    // Find first waiting timer not already active
     447    QTimerInfo *t = 0;
     448    for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) {
     449        if (!(*it)->inTimerEvent) {
     450            t = *it;
     451            break;
     452        }
     453    }
     454
     455    if (!t)
     456      return false;
     457
    427458    if (currentTime < t->timeout) {
    428459        // time to wait
     
    592623
    593624QEventDispatcherUNIX::~QEventDispatcherUNIX()
    594 { }
     625{
     626    Q_D(QEventDispatcherUNIX);
     627    d->threadData->eventDispatcher = 0;
     628}
    595629
    596630int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    597631                                 timeval *timeout)
    598632{
    599     Q_D(QEventDispatcherUNIX);
    600     if (timeout) {
    601         // handle the case where select returns with a timeout, too
    602         // soon.
    603         timeval tvStart = d->timerList.currentTime;
    604         timeval tvCurrent = tvStart;
    605         timeval originalTimeout = *timeout;
    606 
    607         int nsel;
    608         do {
    609             timeval tvRest = originalTimeout + tvStart - tvCurrent;
    610             nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest);
    611             d->timerList.getTime(tvCurrent);
    612         } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout);
    613 
    614         return nsel;
    615     }
    616 
    617     return ::select(nfds, readfds, writefds, exceptfds, timeout);
     633    return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout);
    618634}
    619635
     
    699715QSockNotType::~QSockNotType()
    700716{
    701     while (!list.isEmpty())
    702         delete list.takeFirst();
     717    )
     718        delete list;
    703719}
    704720
     
    736752    int i;
    737753    for (i = 0; i < list.size(); ++i) {
    738         QSockNot *p = list.at(i);
     754        QSockNot *p = list;
    739755        if (p->fd < sockfd)
    740756            break;
     
    774790    int i;
    775791    for (i = 0; i < list.size(); ++i) {
    776         sn = list.at(i);
     792        sn = list;
    777793        if(sn->obj == notifier && sn->fd == sockfd)
    778794            break;
     
    792808            if (!d->sn_vec[i].list.isEmpty())
    793809                d->sn_highest = qMax(d->sn_highest,  // list is fd-sorted
    794                                      d->sn_vec[i].list.first()->fd);
     810                                     d->sn_vec[i].list->fd);
    795811        }
    796812    }
     
    816832    int i;
    817833    for (i = 0; i < list.size(); ++i) {
    818         sn = list.at(i);
     834        sn = list;
    819835        if(sn->obj == notifier && sn->fd == sockfd)
    820836            break;
     
    924940    if (d->wakeUps.testAndSetAcquire(0, 1)) {
    925941        char c = 0;
    926         ::write( d->thread_pipe[1], &c, 1 );
     942        write( d->thread_pipe[1], &c, 1 );
    927943    }
    928944}
Note: See TracChangeset for help on using the changeset viewer.