c - Always print EAGAIN when calling accept after epoll_wait -
i'm using epoll monitor listen fd event, after epollin event occur call accept process, eagain error. can give me suggestions? thanks!
[log] print information below time
info jan 01 00:02:08:924 [385] poll_loop: epoll has 1 event
info jan 01 00:02:08:925 [385] poll_loop: event fd 0, event type:1
info jan 01 00:02:08:925 [385] handle_connect: fd 0,
error jan 01 00:02:08:925 [385] handle_connect: accept returned error 11 resource temporarily unavailable ... retrying, listen fd:0.
[code]
................ 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); (i = 0; < 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 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 fd %d there", *evt, fd); } }
this line says all:
info jan 01 00:02:08:925 [385] poll_loop: event fd 0, event type:1
fd 0 stdin, not listening socket. evidently, adding "0" epoll set instead of listening socket.
you didn't show epoll_ctl getting called add listenfd epoll set (g_epollfd). presumably, that's register_read() call above about. expect this:
int result; epoll_event readevent = {}; readevent.data.fd = listenfd; readevent.events = epollin; result = epoll_ctl(g_epollfd, epoll_ctl_add, listenfd, &readevent);
notice listenfd specified both third parameter epoll_ctl member var on fourth parameter (readevent.data.fd).
Comments
Post a Comment