?? qeventdispatcher_unix.cpp
字號:
} 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 || unsigned(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 || unsigned(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((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); 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) { d->timerList.updateWatchTime(currentTime); first = false; } if (d->timerList.isEmpty()) break; 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->timerList.timerInsert(t); if (t->interval.tv_usec > 0 || t->interval.tv_sec > 0) n_act++; if (!t->inTimerEvent) { // send event, but don't allow it to recurse t->inTimerEvent = true; QTimerEvent e(t->id); QCoreApplication::sendEvent(t->obj, &e); if (d->timerList.contains(t)) t->inTimerEvent = false; } 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; } } 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; 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 + -