我使用epoll来监听listen fd事件,在EPOLLIN事件发生后我调用accept来处理,但总是EAGAIN错误。任何人都可以给我一些建议吗?谢谢!
[log]一直打印下面的信息
信息 Jan 01 00:02:08:924 [385] poll_loop: epoll 有 1 个事件
信息 Jan 01 00:02:08:925 [385] poll_loop:事件 fd 0,事件类型:1
信息 Jan 01 00:02:08:925 [385] handle_connect: fd 0,
错误 Jan 01 00:02:08:925 [385] handle_connect:accept 返回错误 11 资源暂时不可用...重试,听 fd:0。
[代码]
................
listenfd = listen_sock (port, &addrlen);
socket_nonblocking(listenfd);
g_epollFd = epoll_create(MAX_EVENTS);
register_read(listenfd);
.................
while (!config.quit)
{
int fds = epoll_wait(g_epollFd, g_Events, MAX_EVENTS, -1);
if (fds < 0)
{
log_message(LOG_CRIT, "epoll wait error %d %s, continue", errno, strerror(errno));
continue;
}
log_message(LOG_INFO, "epoll has %d event", fds);
for (i = 0; i < fds; ++i)
{
log_message(LOG_INFO, "event fd %d, event type:%d", g_Events[i].data.fd, g_Events[i].events);
if ((g_Events[i].events & EPOLLERR)
|| (g_Events[i].events & EPOLLHUP)
/*|| (g_Events[i].events & POLLNVAL) compile err*/)
{
log_message(LOG_INFO, "A disconnect occurs, [fd:%d]", g_Events[i].data.fd);
handle_disconnect(g_Events[i].data.fd);
continue;
}
if (g_Events[i].events & EPOLLIN)
{
if (listenfd == g_Events[i].data.fd)
{
handle_connect(listenfd, ptr);
}
else if (g_dnsfd == g_Events[i].data.fd)
{
dns_poll(g_dns);
}
else
{
handle_input(g_Events[i].data.fd);
}
}
...................
void handle_connect(int fd, struct child_s *ptr)
{
int connfd;
struct conn_s *connptr = 0;
char peer_ipaddr[IP_LENGTH];
socklen_t clilen = sizeof(struct sockaddr_in);
struct sockaddr_in cliaddr ;
log_message(LOG_INFO, "fd %d, ");
connfd = accept (fd, (struct sockaddr*)(&cliaddr), &clilen);
if (connfd < 0)
{
log_message (LOG_ERR, "accept returned an error %d %s ... retrying, listen fd:%d", errno, strerror (errno), fd);
return;
}
......................
#define REGISTER_EPOLL_EVENT(_fd, evt, op) \
do\
{\
struct epoll_event epv = {0, {0}}; \
epv.data.fd = _fd; \
epv.events = evt; /*EPOLLLT default*/\
\
if(epoll_ctl(g_epollFd, op, _fd, &epv) < 0) \
{\
/*if ((errno != EEXIST) && (errno != ENOENT))*/\
{\
log_message(LOG_ERR, "epool ctl set failed, fd %d, errno %d: %s", _fd, errno, strerror(errno)); \
return ;\
}\
}\
log_message(LOG_INFO, "epool ctl set sucess, fd %d", _fd);\
}while(0)
void register_read(int fd, int* evt)
{
if (0 == evt)
{
REGISTER_EPOLL_EVENT(fd, EPOLLIN, EPOLL_CTL_ADD);
}
else if (0 == *evt)
{
*evt |= EPOLLIN;
REGISTER_EPOLL_EVENT(fd, (*evt), EPOLL_CTL_ADD);
}
else if (!(*evt & EPOLLIN))
{
*evt |= EPOLLIN;
REGISTER_EPOLL_EVENT(fd, (*evt), EPOLL_CTL_MOD);
}
else
{
log_message("event %d for fd %d is already there", *evt, fd);
}
}