Skip to content

Commit

Permalink
Example: fix listen queue overflow.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
logwang committed Dec 21, 2017
1 parent c4e752f commit b2dbf8f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 43 deletions.
51 changes: 21 additions & 30 deletions example/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 nclientfd = ff_accept(sockfd, NULL, NULL);
if (nclientfd < 0) {
printf("ff_accept failed:%d, %s\n", errno, strerror(errno));
continue;
}

/* Add to event list */
kevSet.data = 0;
kevSet.fflags = 0;
kevSet.filter = EVFILT_READ;
kevSet.flags = EV_ADD;
kevSet.ident = nclientfd;
kevSet.udata = NULL;

assert(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) == 0);

//printf("A new client connected to the server..., fd:%d\n", nclientfd);

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));
break;
}

/* Add to event list */
EV_SET(&kevSet, nclientfd, EVFILT_READ, EV_ADD, 0, 0, NULL);

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);
}
Expand Down Expand Up @@ -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);

Expand Down
27 changes: 14 additions & 13 deletions example/main_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,34 @@ int loop(void *arg)
for (i = 0; i < nevents; ++i) {
/* Handle new connect */
if (events[i].data.fd == sockfd) {
int nclientfd = ff_accept(sockfd, NULL, NULL);
if (nclientfd < 0) {
printf("ff_accept failed:%d, %s\n", errno, strerror(errno));
continue;
}
while (1) {
int nclientfd = ff_accept(sockfd, NULL, NULL);
if (nclientfd < 0) {
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);
/* Add to event list */
ev.data.fd = nclientfd;
ev.events = EPOLLIN;
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);
Expand Down

0 comments on commit b2dbf8f

Please sign in to comment.