Changeset 665


Ignore:
Timestamp:
Mar 10, 2010, 1:33:14 AM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: Sockets: Fixed: "has data to read" socket notifications would be sometimes delivered with a delay depending on the frequency of timers which could significantly slow down network data transfer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/kernel/qeventdispatcher_pm.cpp

    r664 r665  
    322322    int refcnt;
    323323    QWaitCondition cond;
    324     bool cancelWait;
    325324
    326325    // socket stuff
     
    331330
    332331    fd_set readS, writeS, exS;
    333     int maxSockfd;
     332    int maxSockfd;
    334333
    335334    // timer stuff
     
    699698
    700699QSelectThread::QSelectThread()
    701     : finish(false), refcnt(0), cancelWait(false), allTimersPosted(false)
     700    : finish(false), refcnt(0), allTimersPosted(false)
    702701{
    703702    // initialize socket stuff
     
    705704    FD_ZERO(&writeS);
    706705    FD_ZERO(&exS);
    707     maxSockfd = -1;
     706    maxSockfd = -1;
    708707
    709708    // initialize timer stuff
     
    786785        if (maxSockfd >= 0) {
    787786            fd_set tmpRead = readS, tmpWrite = writeS, tmpEx = exS;
     787
    788788            mutex.unlock();
    789             nsel = ::select(maxSockfd + 1, &tmpRead, &tmpWrite, &tmpEx, timeout);
     789            nsel = ::select(maxSockfd
    790790            if (nsel == -1 && errno == EINVAL) {
    791791                qWarning("QSocketNotifier: select() returned EINVAL, check that "
    792792                         "the socket is not an OS/2 file handle.");
    793                 // give it some sleep to let other threads do something
    794                 DosSleep(100);
     793                // give it some sleep to avoid 100% CPU load due to select()
     794                // constantly failing in a tight loop which freezes the system
     795                msleep(100);
    795796            }
    796797            mutex.lock();
     
    814815                    }
    815816                    if (isSet) {
     817
     818
     819
    816820                        FD_CLR(sockfd, setForType(type));
    817821                        updateMaxSockFd(sockfd, Remove);
     
    822826        } else {
    823827            nsel = -1;
    824             errno = EINTR;
    825             if (!cancelWait) {
    826                 long msecs = timeout ?
    827                     timeout->tv_sec * 1000l + timeout->tv_usec / 1000l : LONG_MAX;
    828                 if (!cond.wait(&mutex, msecs))
    829                     nsel = 0; // indicate timeout
    830             }
    831             cancelWait = false;
     828            errno = EINTR; // indicate interrupt
     829            long msecs = timeout ?
     830                timeout->tv_sec * 1000l + timeout->tv_usec / 1000l : LONG_MAX;
     831            maxSockfdInSelect = -1;
     832            if (!cond.wait(&mutex, msecs))
     833                nsel = 0; // indicate timeout
    832834        }
    833835
     
    846848void QSelectThread::cancelSelectOrIdle()
    847849{
    848     if (maxSockfd >= 0) {
     850    if (maxSockfdInSelect < 0) {
     851        // terminate the idle or simple wait state
     852        cond.wakeOne();
     853    } else {
    849854        // terminate select() execution
    850         ::so_cancel(maxSockfd);
    851     } else {
    852         // terminate the idle or simple wait state
    853         if (!cancelWait) {
    854             cancelWait = true;
    855             cond.wakeOne();
    856         }
     855        ::so_cancel(maxSockfdInSelect);
    857856    }
    858857}
Note: See TracChangeset for help on using the changeset viewer.