mirror of https://github.com/ericonr/sndio.git
Don't spin if accept() fails because it is out of file descriptors,
instead set a flag that skips the listening socket from the poll() event loop. The flag is cleared whenever a file descriptor is closed allowing accept() to be retried. Explained by deraadt@
This commit is contained in:
parent
2b23e80702
commit
2d72ee38d1
|
@ -73,6 +73,7 @@ struct timespec file_ts;
|
|||
struct filelist file_list;
|
||||
struct timo *timo_queue;
|
||||
unsigned timo_abstime;
|
||||
int file_slowaccept = 0;
|
||||
#ifdef DEBUG
|
||||
long long file_wtime, file_utime;
|
||||
#endif
|
||||
|
|
|
@ -68,6 +68,7 @@ struct file {
|
|||
LIST_HEAD(filelist,file);
|
||||
|
||||
extern struct filelist file_list;
|
||||
extern int file_slowaccept;
|
||||
|
||||
#ifdef DEBUG
|
||||
extern long long file_wtime, file_utime;
|
||||
|
|
|
@ -175,6 +175,8 @@ listen_pollfd(struct file *file, struct pollfd *pfd, int events)
|
|||
{
|
||||
struct listen *f = (struct listen *)file;
|
||||
|
||||
if (file_slowaccept)
|
||||
return 0;
|
||||
pfd->fd = f->fd;
|
||||
pfd->events = POLLIN;
|
||||
return 1;
|
||||
|
@ -190,9 +192,12 @@ listen_revents(struct file *file, struct pollfd *pfd)
|
|||
|
||||
if (pfd->revents & POLLIN) {
|
||||
caddrlen = sizeof(caddrlen);
|
||||
sock = accept(f->fd, &caddr, &caddrlen);
|
||||
if (sock < 0) {
|
||||
/* XXX: should we kill the socket here ? */
|
||||
while ((sock = accept(f->fd, &caddr, &caddrlen)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == ENFILE || errno == EMFILE)
|
||||
file_slowaccept = 1;
|
||||
else
|
||||
perror("accept");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ pipe_close(struct file *file)
|
|||
struct pipe *f = (struct pipe *)file;
|
||||
|
||||
close(f->fd);
|
||||
file_slowaccept = 0;
|
||||
}
|
||||
|
||||
off_t
|
||||
|
|
Loading…
Reference in New Issue