⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qeventdispatcher_unix.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}/*!    \internal*/bool QEventDispatcherUNIX::unregisterTimers(QObject *object){    if (!object) {        qWarning("QEventDispatcherUNIX::unregisterTimers: invalid argument");        return false;    } else if (object->thread() != thread() || thread() != QThread::currentThread()) {        qWarning("QObject::killTimers: timers cannot be stopped from another thread");        return false;    }    Q_D(QEventDispatcherUNIX);    if (d->timerList.isEmpty())        return false;    for (int i = 0; i < d->timerList.size(); ++i) {        register QTimerInfo *t = d->timerList.at(i);        if (t->obj == object) {            // object found            d->timerList.removeAt(i);            delete t;            // move back one so that we don't skip the new current item            --i;        }    }    return true;}QList<QEventDispatcherUNIX::TimerInfo>QEventDispatcherUNIX::registeredTimers(QObject *object) const{    if (!object) {        qWarning("QEventDispatcherUNIX:registeredTimers: invalid argument");        return QList<TimerInfo>();    }    Q_D(const QEventDispatcherUNIX);    QList<TimerInfo> list;    for (int i = 0; i < d->timerList.size(); ++i) {        register const QTimerInfo * const t = d->timerList.at(i);        if (t->obj == object)            list << TimerInfo(t->id, t->interval.tv_sec * 1000 + t->interval.tv_usec / 1000);    }    return list;}/***************************************************************************** Socket notifier type *****************************************************************************/QSockNotType::QSockNotType(){    FD_ZERO(&select_fds);    FD_ZERO(&enabled_fds);    FD_ZERO(&pending_fds);}QSockNotType::~QSockNotType(){    while (!list.isEmpty())        delete list.takeFirst();}/***************************************************************************** QEventDispatcher implementations for UNIX *****************************************************************************/void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier){    int sockfd;    int type;    if (!notifier        || (sockfd = notifier->socket()) < 0        || sockfd > FD_SETSIZE        || (type = notifier->type()) < 0        || type > 2) {        qWarning("QSocketNotifier: Internal error");        return;    } else if (notifier->thread() != thread()               || thread() != QThread::currentThread()) {        qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");        return;    }    Q_D(QEventDispatcherUNIX);    QList<QSockNot *> &list = d->sn_vec[type].list;    fd_set *fds  = &d->sn_vec[type].enabled_fds;    QSockNot *sn;    sn = new QSockNot;    sn->obj = notifier;    sn->fd = sockfd;    sn->queue = &d->sn_vec[type].pending_fds;    int i;    for (i = 0; i < list.size(); ++i) {        QSockNot *p = list.at(i);        if (p->fd < sockfd)            break;        if (p->fd == sockfd) {            static const char *t[] = { "read", "write", "exception" };            qWarning("QSocketNotifier: Multiple socket notifiers for "                      "same socket %d and type %s", sockfd, t[type]);        }    }    list.insert(i, sn);    FD_SET(sockfd, fds);    d->sn_highest = qMax(d->sn_highest, sockfd);}void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier){    int sockfd;    int type;    if (!notifier        || (sockfd = notifier->socket()) < 0        || sockfd > FD_SETSIZE        || (type = notifier->type()) < 0        || type > 2) {        qWarning("QSocketNotifier: Internal error");        return;    } else if (notifier->thread() != thread()               || thread() != QThread::currentThread()) {        qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");        return;    }    Q_D(QEventDispatcherUNIX);    QList<QSockNot *> &list = d->sn_vec[type].list;    fd_set *fds  =  &d->sn_vec[type].enabled_fds;    QSockNot *sn;    int i;    for (i = 0; i < list.size(); ++i) {        sn = list.at(i);        if(sn->obj == notifier && sn->fd == sockfd)            break;    }    if (i == list.size()) // not found        return;    FD_CLR(sockfd, fds);                        // clear fd bit    FD_CLR(sockfd, sn->queue);    d->sn_pending_list.removeAll(sn);                // remove from activation list    list.removeAt(i);                                // remove notifier found above    delete sn;    if (d->sn_highest == sockfd) {                // find highest fd        d->sn_highest = -1;        for (int i=0; i<3; i++) {            if (!d->sn_vec[i].list.isEmpty())                d->sn_highest = qMax(d->sn_highest,  // list is fd-sorted                                     d->sn_vec[i].list.first()->fd);        }    }}void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier){    int sockfd;    int type;    if (!notifier        || (sockfd = notifier->socket()) < 0        || sockfd > FD_SETSIZE        || (type = notifier->type()) < 0        || type > 2) {        qWarning("QSocketNotifier: Internal error");        return;    }    Q_ASSERT(notifier->thread() == thread() && thread() == QThread::currentThread());    Q_D(QEventDispatcherUNIX);    QList<QSockNot *> &list = d->sn_vec[type].list;    QSockNot *sn = 0;    int i;    for (i = 0; i < list.size(); ++i) {        sn = list.at(i);        if(sn->obj == notifier && sn->fd == sockfd)            break;    }    if (i == list.size()) // not found        return;    // We choose a random activation order to be more fair under high load.    // If a constant order is used and a peer early in the list can    // saturate the IO, it might grab our attention completely.    // Also, if we're using a straight list, the callback routines may    // delete other entries from the list before those other entries are    // processed.    if (! FD_ISSET(sn->fd, sn->queue)) {        d->sn_pending_list.insert((rand() & 0xff) %                                   (d->sn_pending_list.size()+1), sn);        FD_SET(sn->fd, sn->queue);    }}int QEventDispatcherUNIX::activateTimers(){    Q_ASSERT(thread() == QThread::currentThread());    Q_D(QEventDispatcherUNIX);    if (qt_disable_lowpriority_timers || d->timerList.isEmpty())        return 0; // nothing to do    bool first = true;    timeval currentTime;    int n_act = 0, maxCount = d->timerList.size();    QTimerInfo *begin = 0;    while (maxCount--) {        getTime(currentTime);        if (first) {            if (currentTime < d->watchtime)                d->timerRepair(currentTime); // clock was turned back            first = false;            d->watchtime = currentTime;        }        if (d->timerList.isEmpty()) break;        register QTimerInfo *t = d->timerList.first();        if (currentTime < t->timeout)            break; // no timer has expired        if (!begin) {            begin = t;        } else if (begin == t) {            // avoid sending the same timer multiple times            break;        } else if (t->interval <  begin->interval || t->interval == begin->interval) {            begin = t;        }        // remove from list        d->timerList.removeFirst();        t->timeout += t->interval;        if (t->timeout < currentTime)            t->timeout = currentTime + t->interval;        // reinsert timer        d->timerInsert(t);        if (t->interval.tv_usec > 0 || t->interval.tv_sec > 0)            n_act++;        // send event        QTimerEvent e(t->id);        QCoreApplication::sendEvent(t->obj, &e);        if (!d->timerList.contains(begin)) begin = 0;    }    return n_act;}int QEventDispatcherUNIX::activateSocketNotifiers(){    Q_D(QEventDispatcherUNIX);    if (d->sn_pending_list.isEmpty())        return 0;    // create sets that match the current pending sets (note: we skip    // the first one, because we activate first and check second)    fd_set rset, wset, xset;    FD_ZERO(&rset);    FD_ZERO(&wset);    FD_ZERO(&xset);    for (int i = 1; i < d->sn_pending_list.size(); ++i) {        const QSockNot * const sn = d->sn_pending_list.at(i);        switch (sn->obj->type()) {        case QSocketNotifier::Read:            FD_SET(sn->fd, &rset);            break;        case QSocketNotifier::Write:            FD_SET(sn->fd, &wset);            break;        case QSocketNotifier::Exception:            FD_SET(sn->fd, &xset);            break;        }    }    // activate entries    int n_act = 0;    QEvent event(QEvent::SockAct);    while (!d->sn_pending_list.isEmpty()) {        QSockNot *sn = d->sn_pending_list.takeFirst();        if (FD_ISSET(sn->fd, sn->queue)) {            FD_CLR(sn->fd, sn->queue);            QCoreApplication::sendEvent(sn->obj, &event);            n_act++;        }        if (d->sn_pending_list.isEmpty())            break;        // check if any fds are no longer pending        int ret = -1;        do {            timeval zero_timeout = { 0l, 0l };            ret = ::select(d->sn_highest + 1, &rset, &wset, &xset, &zero_timeout);        } while (ret == -1 && (errno == EINTR || errno == EAGAIN));        if (ret < -1) {            // any errors caught here are new errors, so we punt and            // let doSelect() handle them            break;        }        for (int i = 0; i < d->sn_pending_list.size(); ++i) {            QSockNot *sn = d->sn_pending_list.at(i);            fd_set *set = 0;            switch (sn->obj->type()) {            case QSocketNotifier::Read:                set = &rset;                break;            case QSocketNotifier::Write:                set = &wset;                break;            case QSocketNotifier::Exception:                set = &xset;                break;            }            if (set && !FD_ISSET(sn->fd, set)) {                // fd is no longer pending                FD_CLR(sn->fd, set);                FD_CLR(sn->fd, sn->queue);                d->sn_pending_list.removeAt(i--);            }        }    }    return n_act;}bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags){    Q_D(QEventDispatcherUNIX);    d->interrupt = false;            // we are awake, broadcast it    emit awake();    QCoreApplication::sendPostedEvents(0, (flags & QEventLoop::DeferredDeletion) ? -1 : 0);    int nevents = 0;    QThreadData *data = QThreadData::get(thread());    const bool canWait = (data->canWait                          && !d->interrupt                          && (flags & QEventLoop::WaitForMoreEvents));    if (canWait)        emit aboutToBlock();    if (!d->interrupt) {        // return the maximum time we can wait for an event.        timeval *tm = 0;        timeval wait_tm = { 0l, 0l };        if (!(flags & QEventLoop::X11ExcludeTimers)) {            if (d->timerWait(wait_tm))                tm = &wait_tm;            if (!canWait) {                if (!tm)                    tm = &wait_tm;                // no time to wait                tm->tv_sec  = 0l;                tm->tv_usec = 0l;            }        }        nevents = d->doSelect(flags, tm);        // activate timers        if (! (flags & QEventLoop::X11ExcludeTimers)) {            nevents += activateTimers();        }    }    // return true if we handled events, false otherwise    return (nevents > 0);}bool QEventDispatcherUNIX::hasPendingEvents(){    extern uint qGlobalPostedEventsCount(); // from qapplication.cpp    return qGlobalPostedEventsCount();}void QEventDispatcherUNIX::wakeUp(){    Q_D(QEventDispatcherUNIX);    if (d->wakeUps.testAndSet(0, 1)) {        char c = 0;        ::write( d->thread_pipe[1], &c, 1 );    }}void QEventDispatcherUNIX::interrupt(){    Q_D(QEventDispatcherUNIX);    d->interrupt = true;    wakeUp();}void QEventDispatcherUNIX::flush(){ }void QCoreApplication::watchUnixSignal(int sig, bool watch){    if (sig < NSIG) {        struct sigaction sa;        sigemptyset(&(sa.sa_mask));        sa.sa_flags = 0;        if (watch)            sa.sa_handler = signalHandler;        else            sa.sa_handler = SIG_DFL;        sigaction(sig, &sa, 0);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -