mirror of https://github.com/F-Stack/f-stack.git
Example: fix listen queue overflow.
According to the FreeBSD Manual Page: - When kevent() returns and if `flags` is EVFILT_READ, sockets which have previously been passed to listen() return when there is an incoming connection pending. `data` contains the size of the listen backlog. So if an EVFILT_READ event reaches and it is the listen socket, we must accept `event->data` times. And for `ff_epoll` interface, we should continue to accept until it fails. In the previous version, we only accept once when event reaches, it will cause listen queue overflow.
This commit is contained in:
parent
c4e752fc00
commit
b2dbf8fd04
|
@ -66,38 +66,34 @@ int loop(void *arg)
|
|||
|
||||
/* Handle disconnect */
|
||||
if (event.flags & EV_EOF) {
|
||||
|
||||
/* Simply close socket */
|
||||
ff_close(clientfd);
|
||||
|
||||
//printf("A client has left the server...,fd:%d\n", clientfd);
|
||||
} else if (clientfd == sockfd) {
|
||||
int available = (int)event.data;
|
||||
do {
|
||||
int nclientfd = ff_accept(sockfd, NULL, NULL);
|
||||
if (nclientfd < 0) {
|
||||
printf("ff_accept failed:%d, %s\n", errno, strerror(errno));
|
||||
continue;
|
||||
printf("ff_accept failed:%d, %s\n", errno,
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add to event list */
|
||||
kevSet.data = 0;
|
||||
kevSet.fflags = 0;
|
||||
kevSet.filter = EVFILT_READ;
|
||||
kevSet.flags = EV_ADD;
|
||||
kevSet.ident = nclientfd;
|
||||
kevSet.udata = NULL;
|
||||
EV_SET(&kevSet, nclientfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
|
||||
|
||||
assert(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) == 0);
|
||||
|
||||
//printf("A new client connected to the server..., fd:%d\n", nclientfd);
|
||||
if(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) < 0) {
|
||||
printf("ff_kevent error:%d, %s\n", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
available--;
|
||||
} while (available);
|
||||
} else if (event.filter == EVFILT_READ) {
|
||||
char buf[256];
|
||||
size_t readlen = ff_read(clientfd, buf, sizeof(buf));
|
||||
|
||||
//printf("bytes %zu are available to read...,fd:%d\n", (size_t)event.data, clientfd);
|
||||
|
||||
ff_write(clientfd, html, sizeof(html));
|
||||
|
||||
} else {
|
||||
printf("unknown event: %8.8X\n", event.flags);
|
||||
}
|
||||
|
@ -133,12 +129,7 @@ int main(int argc, char * argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
kevSet.data = MAX_EVENTS;
|
||||
kevSet.fflags = 0;
|
||||
kevSet.filter = EVFILT_READ;
|
||||
kevSet.flags = EV_ADD;
|
||||
kevSet.ident = sockfd;
|
||||
kevSet.udata = NULL;
|
||||
EV_SET(&kevSet, sockfd, EVFILT_READ, EV_ADD, 0, MAX_EVENTS, NULL);
|
||||
|
||||
assert((kq = ff_kqueue()) > 0);
|
||||
|
||||
|
|
|
@ -65,33 +65,34 @@ int loop(void *arg)
|
|||
for (i = 0; i < nevents; ++i) {
|
||||
/* Handle new connect */
|
||||
if (events[i].data.fd == sockfd) {
|
||||
while (1) {
|
||||
int nclientfd = ff_accept(sockfd, NULL, NULL);
|
||||
if (nclientfd < 0) {
|
||||
printf("ff_accept failed:%d, %s\n", errno, strerror(errno));
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add to event list */
|
||||
ev.data.fd = nclientfd;
|
||||
ev.events = EPOLLIN;
|
||||
assert(ff_epoll_ctl(epfd, EPOLL_CTL_ADD, nclientfd, &ev) == 0);
|
||||
//printf("A new client connected to the server..., fd:%d\n", nclientfd);
|
||||
if (ff_epoll_ctl(epfd, EPOLL_CTL_ADD, nclientfd, &ev) != 0) {
|
||||
printf("ff_epoll_ctl failed:%d, %s\n", errno,
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (events[i].events & EPOLLERR ) {
|
||||
/* Simply close socket */
|
||||
ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
|
||||
ff_close(events[i].data.fd);
|
||||
//printf("A client has left the server...,fd:%d\n", events[i].data.fd);
|
||||
} else if (events[i].events & EPOLLIN) {
|
||||
char buf[256];
|
||||
size_t readlen = ff_read( events[i].data.fd, buf, sizeof(buf));
|
||||
//printf("bytes are available to read..., readlen:%d, fd:%d\n", readlen, events[i].data.fd);
|
||||
if(readlen > 0) {
|
||||
ff_write( events[i].data.fd, html, sizeof(html));
|
||||
} else {
|
||||
ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
|
||||
ff_close( events[i].data.fd);
|
||||
//printf("A client has left the server...,fd:%d\n", events[i].data.fd);
|
||||
}
|
||||
} else {
|
||||
printf("unknown event: %8.8X\n", events[i].events);
|
||||
|
|
Loading…
Reference in New Issue