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);
 | 
							ARRAY_ADD(&dead_clients, c);
 | 
				
			||||||
	c->flags |= CLIENT_DEAD;
 | 
						c->flags |= CLIENT_DEAD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_add_accept(0); /* may be more file descriptors now */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	recalculate_sizes();
 | 
						recalculate_sizes();
 | 
				
			||||||
	server_check_unattached();
 | 
						server_check_unattached();
 | 
				
			||||||
	server_update_socket();
 | 
						server_update_socket();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								server.c
									
									
									
									
									
								
							@@ -191,9 +191,7 @@ server_start(int lockfd, char *lockfile)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	cfg_finished = 1;
 | 
						cfg_finished = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	event_set(&server_ev_accept,
 | 
						server_add_accept(0);
 | 
				
			||||||
	    server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL);
 | 
					 | 
				
			||||||
	event_add(&server_ev_accept, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&tv, 0, sizeof tv);
 | 
						memset(&tv, 0, sizeof tv);
 | 
				
			||||||
	tv.tv_sec = 1;
 | 
						tv.tv_sec = 1;
 | 
				
			||||||
@@ -337,6 +335,7 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
				
			|||||||
	socklen_t		slen = sizeof sa;
 | 
						socklen_t		slen = sizeof sa;
 | 
				
			||||||
	int			newfd;
 | 
						int			newfd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_add_accept(0);
 | 
				
			||||||
	if (!(events & EV_READ))
 | 
						if (!(events & EV_READ))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -344,6 +343,11 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
				
			|||||||
	if (newfd == -1) {
 | 
						if (newfd == -1) {
 | 
				
			||||||
		if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
 | 
							if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
							if (errno == ENFILE || errno == EMFILE) {
 | 
				
			||||||
 | 
								/* Delete and don't try again for 1 second. */
 | 
				
			||||||
 | 
								server_add_accept(1);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		fatal("accept failed");
 | 
							fatal("accept failed");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (server_shutdown) {
 | 
						if (server_shutdown) {
 | 
				
			||||||
@@ -353,6 +357,29 @@ server_accept_callback(int fd, short events, unused void *data)
 | 
				
			|||||||
	server_client_create(newfd);
 | 
						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. */
 | 
					/* Signal handler. */
 | 
				
			||||||
/* ARGSUSED */
 | 
					/* ARGSUSED */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@@ -370,9 +397,7 @@ server_signal_callback(int sig, unused short events, unused void *data)
 | 
				
			|||||||
		event_del(&server_ev_accept);
 | 
							event_del(&server_ev_accept);
 | 
				
			||||||
		close(server_fd);
 | 
							close(server_fd);
 | 
				
			||||||
		server_fd = server_create_socket();
 | 
							server_fd = server_create_socket();
 | 
				
			||||||
		event_set(&server_ev_accept, server_fd,
 | 
							server_add_accept(0);
 | 
				
			||||||
		    EV_READ|EV_PERSIST, server_accept_callback, NULL);
 | 
					 | 
				
			||||||
		event_add(&server_ev_accept, NULL);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1713,6 +1713,7 @@ extern struct clients dead_clients;
 | 
				
			|||||||
extern struct paste_stack global_buffers;
 | 
					extern struct paste_stack global_buffers;
 | 
				
			||||||
int	 server_start(int, char *);
 | 
					int	 server_start(int, char *);
 | 
				
			||||||
void	 server_update_socket(void);
 | 
					void	 server_update_socket(void);
 | 
				
			||||||
 | 
					void	 server_add_accept(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* server-client.c */
 | 
					/* server-client.c */
 | 
				
			||||||
void	 server_client_create(int);
 | 
					void	 server_client_create(int);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user