s64 epoller::DealEvent(s64 overtime) { s64 lTick = tools::GetTimeMillisecond(); epoll_event events[EPOLLER_EVENTS_COUNT]; memset(&events, 0, sizeof(events)); errno = 0; int retCount = epoll_wait(m_lEpollFD, events, EPOLLER_EVENTS_COUNT, 5); if (retCount == -1) { TASSERT(errno == EINTR, "epoll_wait err! %s", strerror(errno)); return tools::GetTimeMillisecond() - lTick; } for (s32 i=0; i<retCount; i++) { epollerEvent * pEvent = (epollerEvent *)events[i].data.ptr; switch (pEvent->type) { case SO_ACCEPT: { SPipe * pSPipe = (SPipe *)pEvent->pData; if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) { pSPipe->GetHost()->Error(Kernel::getInstance(), NULL); } else if (events[i].events & EPOLLIN) { pSPipe->DoAccept(); } break; } case SO_CONNECT: { CPipe * pCPipe = (CPipe *)pEvent->pData; if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) { pCPipe->GetHost()->OnConnectFailed(Kernel::getInstance()); pCPipe->GetHost()->m_pPipe = NULL; pCPipe->Release(); } else if (events[i].events & EPOLLOUT) { pCPipe->DoConnect(); } break; } default: TASSERT(false, "wtf"); break; } } return tools::GetTimeMillisecond() - lTick; }
bool epoller::AddClient(ITcpSession * client, const char * ip, const s32 port) { s64 lSocket = -1; struct timeval tv; struct sockaddr_in addr; memset(&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (-1 == (lSocket = socket(AF_INET, SOCK_STREAM, 0)) || 0 != setsockopt(lSocket, SOL_SOCKET, SO_REUSEADDR, (const char*) &tv, sizeof (tv)) || !setnonblocking(lSocket) || inet_pton(AF_INET, ip, &addr.sin_addr) <= 0) { ECHO("socket error %s", strerror(errno)); close(lSocket); return false; } s32 ret = connect(lSocket, (struct sockaddr *) &addr, sizeof (addr)); if (ret == 0) { CPipe * pCPipe = CPipe::Create(); s64 lEpollFD = BalancingWorker()->GetEpollFD(); pCPipe->Relate(client, lSocket, lEpollFD); pCPipe->DoConnect(); client->OnConnected(Kernel::getInstance()); } else if (ret < 0 && errno != EINPROGRESS) { ECHO("connect error %s", strerror(errno)); client->OnConnectFailed(Kernel::getInstance()); return false; } else { CPipe * pCPipe = CPipe::Create(); s64 lEpollFD = BalancingWorker()->GetEpollFD(); pCPipe->Relate(client, lSocket, lEpollFD); epoll_event ev; ev.data.ptr = (void *)pCPipe->GetEvent(); ev.events = EPOLLOUT | EPOLLET; s32 res = epoll_ctl(m_lEpollFD, EPOLL_CTL_ADD, lSocket, &ev); TASSERT(res == 0, strerror(errno)); } return true; }