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

📄 qeventdispatcher_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        if (t->obj == object) {            // object found            removeAt(i);            if (t == firstTimerInfo)                firstTimerInfo = 0;            if (t == currentTimerInfo)                currentTimerInfo = 0;            delete t;            // move back one so that we don't skip the new current item            --i;        }    }    return true;}QList<QPair<int, int> > QTimerInfoList::registeredTimers(QObject *object) const{    QList<QPair<int, int> > list;    for (int i = 0; i < count(); ++i) {        register const QTimerInfo * const t = at(i);        if (t->obj == object)            list << QPair<int, int>(t->id, t->interval.tv_sec * 1000 + t->interval.tv_usec / 1000);    }    return list;}/*    Activate pending timers, returning how many where activated.*/int QTimerInfoList::activateTimers(){    if (qt_disable_lowpriority_timers || isEmpty())        return 0; // nothing to do    bool firstTime = true;    timeval currentTime;    int n_act = 0, maxCount = count();    QTimerInfo *saveFirstTimerInfo = firstTimerInfo;    QTimerInfo *saveCurrentTimerInfo = currentTimerInfo;    firstTimerInfo = currentTimerInfo = 0;    while (maxCount--) {        currentTime = updateCurrentTime();        if (firstTime) {            repairTimersIfNeeded();            firstTime = false;        }        if (isEmpty())            break;        currentTimerInfo = first();        if (currentTime < currentTimerInfo->timeout)            break; // no timer has expired        if (!firstTimerInfo) {            firstTimerInfo = currentTimerInfo;        } else if (firstTimerInfo == currentTimerInfo) {            // avoid sending the same timer multiple times            break;        } else if (currentTimerInfo->interval <  firstTimerInfo->interval                   || currentTimerInfo->interval == firstTimerInfo->interval) {            firstTimerInfo = currentTimerInfo;        }        // remove from list        removeFirst();        // determine next timeout time        currentTimerInfo->timeout += currentTimerInfo->interval;        if (currentTimerInfo->timeout < currentTime)            currentTimerInfo->timeout = currentTime + currentTimerInfo->interval;        // reinsert timer        timerInsert(currentTimerInfo);        if (currentTimerInfo->interval.tv_usec > 0 || currentTimerInfo->interval.tv_sec > 0)            n_act++;        if (!currentTimerInfo->inTimerEvent) {            // send event, but don't allow it to recurse            currentTimerInfo->inTimerEvent = true;            QTimerEvent e(currentTimerInfo->id);            QCoreApplication::sendEvent(currentTimerInfo->obj, &e);            if (currentTimerInfo)                currentTimerInfo->inTimerEvent = false;        }    }    firstTimerInfo = saveFirstTimerInfo;    currentTimerInfo = saveCurrentTimerInfo;    return n_act;}QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent)    : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent){ }QEventDispatcherUNIX::QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent)    : QAbstractEventDispatcher(dd, parent){ }QEventDispatcherUNIX::~QEventDispatcherUNIX(){ }int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,                                 timeval *timeout){    Q_D(QEventDispatcherUNIX);    if (timeout) {        // handle the case where select returns with a timeout, too        // soon.        timeval tvStart = d->timerList.currentTime;        timeval tvCurrent = tvStart;        timeval originalTimeout = *timeout;        int nsel;        do {            timeval tvRest = originalTimeout + tvStart - tvCurrent;            nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest);            d->timerList.getTime(tvCurrent);        } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout);        return nsel;    }    return ::select(nfds, readfds, writefds, exceptfds, timeout);}/*!    \internal*/void QEventDispatcherUNIX::registerTimer(int timerId, int interval, QObject *obj){#ifndef QT_NO_DEBUG    if (timerId < 1 || interval < 0 || !obj) {        qWarning("QEventDispatcherUNIX::registerTimer: invalid arguments");        return;    } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {        qWarning("QObject::startTimer: timers cannot be started from another thread");        return;    }#endif    Q_D(QEventDispatcherUNIX);    d->timerList.registerTimer(timerId, interval, obj);}/*!    \internal*/bool QEventDispatcherUNIX::unregisterTimer(int timerId){#ifndef QT_NO_DEBUG    if (timerId < 1) {        qWarning("QEventDispatcherUNIX::unregisterTimer: invalid argument");        return false;    } else if (thread() != QThread::currentThread()) {        qWarning("QObject::killTimer: timers cannot be stopped from another thread");        return false;    }#endif    Q_D(QEventDispatcherUNIX);    return d->timerList.unregisterTimer(timerId);}/*!    \internal*/bool QEventDispatcherUNIX::unregisterTimers(QObject *object){#ifndef QT_NO_DEBUG    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;    }#endif    Q_D(QEventDispatcherUNIX);    return d->timerList.unregisterTimers(object);}QList<QEventDispatcherUNIX::TimerInfo>QEventDispatcherUNIX::registeredTimers(QObject *object) const{    if (!object) {        qWarning("QEventDispatcherUNIX:registeredTimers: invalid argument");        return QList<TimerInfo>();    }    Q_D(const QEventDispatcherUNIX);    return d->timerList.registeredTimers(object);}/***************************************************************************** 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){    Q_ASSERT(notifier);    int sockfd = notifier->socket();    int type = notifier->type();#ifndef QT_NO_DEBUG    if (sockfd < 0        || unsigned(sockfd) >= FD_SETSIZE) {        qWarning("QSocketNotifier: Internal error");        return;    } else if (notifier->thread() != thread()               || thread() != QThread::currentThread()) {        qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");        return;    }#endif    Q_D(QEventDispatcherUNIX);    QSockNotType::List &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){    Q_ASSERT(notifier);    int sockfd = notifier->socket();    int type = notifier->type();#ifndef QT_NO_DEBUG    if (sockfd < 0        || unsigned(sockfd) >= FD_SETSIZE) {        qWarning("QSocketNotifier: Internal error");        return;    } else if (notifier->thread() != thread()               || thread() != QThread::currentThread()) {        qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");        return;    }#endif    Q_D(QEventDispatcherUNIX);    QSockNotType::List &list = d->sn_vec[type].list;    fd_set *fds  =  &d->sn_vec[type].enabled_fds;    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;    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){    Q_ASSERT(notifier);    int sockfd = notifier->socket();    int type = notifier->type();#ifndef QT_NO_DEBUG    if (sockfd < 0        || unsigned(sockfd) >= FD_SETSIZE) {        qWarning("QSocketNotifier: Internal error");        return;    }    Q_ASSERT(notifier->thread() == thread() && thread() == QThread::currentThread());#endif    Q_D(QEventDispatcherUNIX);    QSockNotType::List &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)) {        if (d->sn_pending_list.isEmpty()) {            d->sn_pending_list.append(sn);        } else {            d->sn_pending_list.insert((qrand() & 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);    return d->timerList.activateTimers();}int QEventDispatcherUNIX::activateSocketNotifiers(){    Q_D(QEventDispatcherUNIX);    if (d->sn_pending_list.isEmpty())        return 0;    // 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;        }    }    return n_act;}bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags){    Q_D(QEventDispatcherUNIX);    d->interrupt = false;    // we are awake, broadcast it    emit awake();    QCoreApplicationPrivate::sendPostedEvents(0, (flags & QEventLoop::DeferredDeletion) ? -1 : 0, d->threadData);    int nevents = 0;    const bool canWait = (d->threadData->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->timerList.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.testAndSetAcquire(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 + -