mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Stop accepting new clients for 1 second on EMFILE/ENFILE. Based on
ongoing fixes to other daemons by Theo.
This commit is contained in:
		@@ -191,6 +191,8 @@ server_client_lost(struct client *c)
 | 
			
		||||
		ARRAY_ADD(&dead_clients, c);
 | 
			
		||||
	c->flags |= CLIENT_DEAD;
 | 
			
		||||
 | 
			
		||||
	server_add_accept(0); /* may be more file descriptors now */
 | 
			
		||||
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
	server_check_unattached();
 | 
			
		||||
	server_update_socket();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								server.c
									
									
									
									
									
								
							@@ -191,9 +191,7 @@ server_start(int lockfd, char *lockfile)
 | 
			
		||||
	}
 | 
			
		||||
	cfg_finished = 1;
 | 
			
		||||
 | 
			
		||||
	event_set(&server_ev_accept,
 | 
			
		||||
	    server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL);
 | 
			
		||||
	event_add(&server_ev_accept, NULL);
 | 
			
		||||
	server_add_accept(0);
 | 
			
		||||
 | 
			
		||||
	memset(&tv, 0, sizeof tv);
 | 
			
		||||
	tv.tv_sec = 1;
 | 
			
		||||
@@ -337,6 +335,7 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
			
		||||
	socklen_t		slen = sizeof sa;
 | 
			
		||||
	int			newfd;
 | 
			
		||||
 | 
			
		||||
	server_add_accept(0);
 | 
			
		||||
	if (!(events & EV_READ))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
@@ -344,6 +343,11 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
			
		||||
	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,6 +357,29 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
			
		||||
	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,9 +397,7 @@ server_signal_callback(int sig, unused short events, unused void *data)
 | 
			
		||||
		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);
 | 
			
		||||
		server_add_accept(0);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user