EIO_Status CSocketAPI::Poll(vector<SPoll>&  polls,
                            const STimeout* timeout,
                            size_t*         n_ready)
{
    static const STimeout kZero = {0, 0};
    size_t          x_n     = polls.size();
    SPOLLABLE_Poll* x_polls = 0;
    size_t          x_ready = 0;

    if (x_n  &&  !(x_polls = new SPOLLABLE_Poll[x_n]))
        return eIO_Unknown;

    for (size_t i = 0;  i < x_n;  i++) {
        CPollable* p     = polls[i].m_Pollable;
        EIO_Event  event = polls[i].m_Event;
        if (p  &&  event) {
            CSocket* s = dynamic_cast<CSocket*> (p);
            if (!s) {
                CListeningSocket* ls = dynamic_cast<CListeningSocket*> (p);
                if (!ls) {
                    CTrigger* tr = dynamic_cast<CTrigger*> (p);
                    x_polls[i].poll = POLLABLE_FromTRIGGER(tr
                                                           ? tr->GetTRIGGER()
                                                           : 0);
                } else
                    x_polls[i].poll = POLLABLE_FromLSOCK(ls->GetLSOCK());
                polls[i].m_REvent = eIO_Open;
            } else {
                EIO_Event revent;
                if (s->GetStatus(eIO_Open) != eIO_Closed) {
                    x_polls[i].poll = POLLABLE_FromSOCK(s->GetSOCK());
                    revent = eIO_Open;
                } else {
                    x_polls[i].poll = 0;
                    revent = eIO_Close;
                    x_ready++;
                }
                polls[i].m_REvent = revent;
            }
            x_polls[i].event = event;
        } else {
            x_polls[i].poll = 0;
            polls[i].m_REvent = eIO_Open;
        }
    }

    size_t xx_ready;
    EIO_Status status = POLLABLE_Poll(x_n, x_polls,
                                      x_ready ? &kZero : timeout, &xx_ready);

    for (size_t i = 0;  i < x_n;  i++) {
        if (x_polls[i].revent)
            polls[i].m_REvent = x_polls[i].revent;
    }

    if (n_ready)
        *n_ready = xx_ready + x_ready;

    delete[] x_polls;
    return status;
}
Exemplo n.º 2
0
int32_t CEpoll::HandleMessage(int32_t nWaitTimeout)
{
	if(m_nEpollFD < 0)
	{
		return -1;
	}

	int32_t nEventCount = epoll_wait(m_nEpollFD, m_pEpollEvent, m_nMaxFD, nWaitTimeout);
	if(nEventCount < 0)
	{
		return -1;
	}

	for(int32_t i = 0; i < nEventCount; ++i)
	{
		CSocket *pSocket = (CSocket *)m_pEpollEvent[i].data.ptr;
		if(pSocket == NULL)
		{
			continue;
		}

		if((m_pEpollEvent[i].events & EPOLLIN) != 0)
		{
			pSocket->ReadEvent();

			SocketStatus nSocketStatus = pSocket->GetStatus();
			if((nSocketStatus == enmSocketStatus_Closed) || (nSocketStatus == enmSocketStatus_Error))
			{
				continue;
			}
		}
		if((m_pEpollEvent[i].events & EPOLLOUT) != 0)
		{
			pSocket->WriteEvent();

			SocketStatus nSocketStatus = pSocket->GetStatus();
			if((nSocketStatus == enmSocketStatus_Closed) || (nSocketStatus == enmSocketStatus_Error))
			{
				continue;
			}
		}
		if((m_pEpollEvent[i].events & EPOLLERR) != 0)
		{
			pSocket->ErrorEvent();

			SocketStatus nSocketStatus = pSocket->GetStatus();
			if((nSocketStatus == enmSocketStatus_Closed) || (nSocketStatus == enmSocketStatus_Error))
			{
				continue;
			}
		}
		if((m_pEpollEvent[i].events & EPOLLHUP) != 0)
		{
			pSocket->ErrorEvent();

			SocketStatus nSocketStatus = pSocket->GetStatus();
			if((nSocketStatus == enmSocketStatus_Closed) || (nSocketStatus == enmSocketStatus_Error))
			{
				continue;
			}
		}
		if(!(m_pEpollEvent[i].events & EPOLLIN) &&
				!(m_pEpollEvent[i].events & EPOLLOUT) &&
				!(m_pEpollEvent[i].events & EPOLLERR) &&
				!(m_pEpollEvent[i].events & EPOLLHUP))
		{
			g_FrameLogEngine.WriteNetioLog(enmLogLevel_Error, "it's not found ioevent = 0x%08x\n", m_pEpollEvent[i].events);
		}
	}

	return nEventCount;
}