void TimerManager::executeTimers() { std::vector<boost::function<void ()> > expired = processTimers(); // Run the callbacks for each expired timer (not under a lock) for (std::vector<boost::function<void ()> >::iterator it(expired.begin()); it != expired.end(); ++it) { (*it)(); } }
void interrupt isr(void) { // Timer0 if((T0IE) && (T0IF)) { processSwitch(); processTimers(); processWiper(); T0IF = 0; } }
int32 EventLoop::run() { SDK_LOG(LOG_LEVEL_TRACE, "eventloop run"); const struct timeval c_tvmax = { LONG_MAX, LONG_MAX }; struct timeval tv; struct timeval* ptv; fd_set fds; while (m_run) { tv = c_tvmax; processTimers(tv); ptv = (tv_cmp(c_tvmax, tv) == 0) ? NULL : &tv; FD_ZERO(&fds); SOCKET maxfd = m_ctlfdr; FD_SET(m_ctlfdr, &fds); for (CliConnMap::iterator it = m_conns.begin(); it != m_conns.end();it++) { CliConn* pcon = it->second; if (pcon && pcon->getfd() != INVALID_SOCKET) { FD_SET(pcon->getfd(), &fds); maxfd = (maxfd >= pcon->getfd()) ? maxfd:pcon->getfd(); } } maxfd++; //SDK_LOG(LOG_LEVEL_TRACE, "select time out = %s", itostr(tv.tv_sec).c_str()); int32 ret = select(maxfd, &fds, NULL, NULL, ptv); if (ret < 0) { if (ret != /*SOCK_EINTR*/4) { SDK_LOG(LOG_LEVEL_TRACE, "select error %d", ret); return -1; } } else if (ret == 0) { //time out } else { if (FD_ISSET(m_ctlfdr, &fds)) { processOps(); } std::vector<std::string> errconns; for (CliConnMap::iterator it = m_conns.begin(); it != m_conns.end(); it++) { CliConn* pcon = it->second; if (pcon && FD_ISSET(pcon->getfd(), &fds)) { if (pcon->handleRead() < 0) { pcon->onDisconnect(true, MY_NETWORK_ERROR); errconns.push_back(pcon->getCid()); } } } for (std::vector<std::string>::iterator it = errconns.begin(); it != errconns.end(); ++it) { delConn(*it); } } } //onStopAndWait(); SDK_LOG(LOG_LEVEL_TRACE, "eventloop exit"); return 0; }
int32 EventLoop::run() { int32 ret = 0; int32 nfds = 0; m_status = STATUS_RUNNING; NLogError << "EventLoop:" << std::hex << this << " run start!"; struct epoll_event events[MAX_PROC_EVENT_CNT]; int32 events_on_loop = MAX_PROC_EVENT_CNT < NetSettings::procEventCnt ? MAX_PROC_EVENT_CNT : NetSettings::procEventCnt; time_tv tv; while(1) { //process Op and timer at first processOps(); int64 t = processTimers(); if(m_status != STATUS_RUNNING&& !ConnectionsCount()) { m_status = STATUS_CLOSED; break; } if(t > 0) { nfds = epoll_wait(m_epl,events, events_on_loop, t); } else { nfds = epoll_wait(m_epl,events, events_on_loop, -1); } if(nfds < 0) { NLogTrace << "EventLoop:" << std::hex << this << ", epoll error,errno:" << errno; if(errno != SOCK_EINTR) { break; } } for(int32 i = 0; i < nfds && i < events_on_loop; ++i) { if(events[i].data.fd == m_ctlfd) { //std::cout << "epoll m_ctlfd"<< std::endl; continue; } std::string addr; int32 port; Device* con = (Device*)events[i].data.ptr; con->getAddr(addr,port); if(events[i].events & EPOLLIN) { ret = con->handleRead(this); } else if(events[i].events & EPOLLOUT) { ret = con->handleWrite(this); } else { ret = -1; } if(ret < 0) { NLogWarn << "EventLoop:" << std::hex << this << ", con:" << std::hex << con << std::dec << ", fd:" << con->getFd() << ", " << (addr) << ":" << port << " handle event:" << events[i].events << " fail, recycle!"; con->onFail(); continue; } #if DETAIL_NET_LOG else { NLogTrace << "EventLoop:" << std::hex << this << ", con:" << std::hex << con << std::dec << ", fd:" << con->getFd() << ", " << (addr) << ":" << port << " handle event success!"; } #endif } } NLogError << "EventLoop:" << std::hex << this << " run stop!"; return 0; }
void IOManagerEPoll::idle() { epoll_event events[64]; while (true) { unsigned long long nextTimeout; if (stopping(nextTimeout)) return; int rc = -1; errno = EINTR; while (rc < 0 && errno == EINTR) { int timeout = -1; if (nextTimeout != ~0ull) timeout = (int)(nextTimeout / 1000) + 1; rc = epoll_wait(m_epfd, events, 64, timeout); if (rc < 0 && errno == EINTR) nextTimeout = nextTimer(); } MORDOR_LOG_LEVEL(g_log, rc < 0 ? Log::ERROR : Log::VERBOSE) << this << " epoll_wait(" << m_epfd << "): " << rc << " (" << errno << ")"; if (rc < 0) MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("epoll_wait"); std::vector<boost::function<void ()> > expired = processTimers(); schedule(expired.begin(), expired.end()); for(int i = 0; i < rc; ++i) { epoll_event &event = events[i]; if (event.data.fd == m_tickleFds[0]) { unsigned char dummy; int rc2 = read(m_tickleFds[0], &dummy, 1); MORDOR_VERIFY(rc2 == 1); MORDOR_LOG_VERBOSE(g_log) << this << " received tickle"; continue; } bool err = event.events & (EPOLLERR | EPOLLHUP); boost::mutex::scoped_lock lock(m_mutex); std::map<int, AsyncEvent>::iterator it = m_pendingEvents.find(event.data.fd); if (it == m_pendingEvents.end()) continue; AsyncEvent &e = it->second; MORDOR_LOG_TRACE(g_log) << " epoll_event {" << (epoll_events_t)event.events << ", " << event.data.fd << "}, registered for " << (epoll_events_t)e.event.events; if ((event.events & EPOLLERR) && (e.event.events & EPOLLERR)) { if (e.m_dgError) e.m_schedulerError->schedule(e.m_dgError); else e.m_schedulerError->schedule(e.m_fiberError); // Block other events from firing e.m_dgError = NULL; e.m_fiberError.reset(); e.m_dgIn = NULL; e.m_fiberIn.reset(); e.m_dgOut = NULL; e.m_fiberOut.reset(); event.events = 0; e.event.events = 0; } if ((event.events & EPOLLHUP) && (e.event.events & EPOLLHUP)) { if (e.m_dgClose) e.m_schedulerError->schedule(e.m_dgClose); else e.m_schedulerError->schedule(e.m_fiberClose); // Block write event from firing e.m_dgOut = NULL; e.m_fiberOut.reset(); e.m_dgClose = NULL; e.m_fiberClose.reset(); event.events &= EPOLLOUT; e.event.events &= EPOLLOUT; err = false; } if (((event.events & EPOLLIN) || err) && (e.event.events & EPOLLIN)) { if (e.m_dgIn) e.m_schedulerIn->schedule(e.m_dgIn); else e.m_schedulerIn->schedule(e.m_fiberIn); e.m_dgIn = NULL; e.m_fiberIn.reset(); event.events |= EPOLLIN; } if (((event.events & EPOLLOUT) || err) && (e.event.events & EPOLLOUT)) { if (e.m_dgOut) e.m_schedulerOut->schedule(e.m_dgOut); else e.m_schedulerOut->schedule(e.m_fiberOut); e.m_dgOut = NULL; e.m_fiberOut.reset(); event.events |= EPOLLOUT; } e.event.events &= ~event.events; int op = e.event.events == 0 ? EPOLL_CTL_DEL : EPOLL_CTL_MOD; int rc2 = epoll_ctl(m_epfd, op, event.data.fd, &e.event); MORDOR_LOG_LEVEL(g_log, rc2 ? Log::ERROR : Log::VERBOSE) << this << " epoll_ctl(" << m_epfd << ", " << (epoll_ctl_op_t)op << ", " << event.data.fd << ", " << (epoll_events_t)e.event.events << "): " << rc2 << " (" << errno << ")"; if (rc2) MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("epoll_ctl"); if (op == EPOLL_CTL_DEL) m_pendingEvents.erase(it); } Fiber::yield(); } }