diff --git a/aucat/file.c b/aucat/file.c index 107341e..d1034ed 100644 --- a/aucat/file.c +++ b/aucat/file.c @@ -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 diff --git a/aucat/file.h b/aucat/file.h index 2ac4bc0..6a8312c 100644 --- a/aucat/file.h +++ b/aucat/file.h @@ -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; diff --git a/aucat/listen.c b/aucat/listen.c index bdf7c72..31b7f4b 100644 --- a/aucat/listen.c +++ b/aucat/listen.c @@ -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,10 +192,13 @@ 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 ? */ - perror("accept"); + 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; } if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { diff --git a/aucat/pipe.c b/aucat/pipe.c index 8390092..528f7f4 100644 --- a/aucat/pipe.c +++ b/aucat/pipe.c @@ -139,6 +139,7 @@ pipe_close(struct file *file) struct pipe *f = (struct pipe *)file; close(f->fd); + file_slowaccept = 0; } off_t