=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/server.c,v retrieving revision 1.103 retrieving revision 1.104 diff -c -r1.103 -r1.104 *** src/usr.bin/tmux/server.c 2012/03/09 09:57:40 1.103 --- src/usr.bin/tmux/server.c 2012/04/11 06:16:14 1.104 *************** *** 1,4 **** ! /* $OpenBSD: server.c,v 1.103 2012/03/09 09:57:40 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: server.c,v 1.104 2012/04/11 06:16:14 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 191,199 **** } cfg_finished = 1; ! event_set(&server_ev_accept, ! server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL); ! event_add(&server_ev_accept, NULL); memset(&tv, 0, sizeof tv); tv.tv_sec = 1; --- 191,197 ---- } cfg_finished = 1; ! server_add_accept(0); memset(&tv, 0, sizeof tv); tv.tv_sec = 1; *************** *** 337,342 **** --- 335,341 ---- socklen_t slen = sizeof sa; int newfd; + server_add_accept(0); if (!(events & EV_READ)) return; *************** *** 344,349 **** --- 343,353 ---- if (newfd == -1) { if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED) return; + if (errno == ENFILE || errno == EMFILE) { + /* Delete and don't try again for 1 second. */ + server_add_accept(1); + return; + } fatal("accept failed"); } if (server_shutdown) { *************** *** 353,358 **** --- 357,385 ---- server_client_create(newfd); } + /* + * Add accept event. If timeout is nonzero, add as a timeout instead of a read + * event - used to backoff when running out of file descriptors. + */ + void + server_add_accept(int timeout) + { + struct timeval tv = { timeout, 0 }; + + if (event_initialized(&server_ev_accept)) + event_del(&server_ev_accept); + + if (timeout == 0) { + event_set(&server_ev_accept, + server_fd, EV_READ, server_accept_callback, NULL); + event_add(&server_ev_accept, NULL); + } else { + event_set(&server_ev_accept, + server_fd, EV_TIMEOUT, server_accept_callback, NULL); + event_add(&server_ev_accept, &tv); + } + } + /* Signal handler. */ /* ARGSUSED */ void *************** *** 370,378 **** event_del(&server_ev_accept); close(server_fd); server_fd = server_create_socket(); ! event_set(&server_ev_accept, server_fd, ! EV_READ|EV_PERSIST, server_accept_callback, NULL); ! event_add(&server_ev_accept, NULL); break; } } --- 397,403 ---- event_del(&server_ev_accept); close(server_fd); server_fd = server_create_socket(); ! server_add_accept(0); break; } }