Ejemplo n.º 1
0
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)();
    }
}
Ejemplo n.º 2
0
void interrupt isr(void)
{
	// Timer0
	if((T0IE) && (T0IF))
	{
		processSwitch();
		processTimers();
		processWiper();
		
		T0IF = 0;
	}
}
Ejemplo n.º 3
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;
	}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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();
    }
}