mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Reference count clients and sessions rather than relying on a saved index for
cmd-choose-*.
This commit is contained in:
		
							
								
								
									
										44
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								server.c
									
									
									
									
									
								
							@@ -43,6 +43,7 @@
 | 
			
		||||
 | 
			
		||||
/* Client list. */
 | 
			
		||||
struct clients	 clients;
 | 
			
		||||
struct clients	 dead_clients;
 | 
			
		||||
 | 
			
		||||
void		 server_create_client(int);
 | 
			
		||||
int		 server_create_socket(void);
 | 
			
		||||
@@ -61,6 +62,7 @@ int		 server_check_window_activity(struct session *,
 | 
			
		||||
		      struct window *);
 | 
			
		||||
int		 server_check_window_content(struct session *, struct window *,
 | 
			
		||||
		      struct window_pane *);
 | 
			
		||||
void		 server_clean_dead(void);
 | 
			
		||||
void		 server_lost_client(struct client *);
 | 
			
		||||
void	 	 server_check_window(struct window *);
 | 
			
		||||
void		 server_check_redraw(struct client *);
 | 
			
		||||
@@ -85,6 +87,7 @@ server_create_client(int fd)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	c = xcalloc(1, sizeof *c);
 | 
			
		||||
	c->references = 0;
 | 
			
		||||
	imsg_init(&c->ibuf, fd);
 | 
			
		||||
 | 
			
		||||
	ARRAY_INIT(&c->prompt_hdata);
 | 
			
		||||
@@ -162,7 +165,9 @@ server_start(char *path)
 | 
			
		||||
 | 
			
		||||
	ARRAY_INIT(&windows);
 | 
			
		||||
	ARRAY_INIT(&clients);
 | 
			
		||||
	ARRAY_INIT(&dead_clients);
 | 
			
		||||
	ARRAY_INIT(&sessions);
 | 
			
		||||
	ARRAY_INIT(&dead_sessions);
 | 
			
		||||
	mode_key_init_trees();
 | 
			
		||||
	key_bindings_init();
 | 
			
		||||
	utf8_build();
 | 
			
		||||
@@ -344,6 +349,9 @@ server_main(int srv_fd)
 | 
			
		||||
 | 
			
		||||
		/* Collect any unset key bindings. */
 | 
			
		||||
		key_bindings_clean();
 | 
			
		||||
 | 
			
		||||
		/* Collect dead clients and sessions. */
 | 
			
		||||
		server_clean_dead();
 | 
			
		||||
		
 | 
			
		||||
		/*
 | 
			
		||||
		 * If we have no sessions and clients left, let's get out
 | 
			
		||||
@@ -948,11 +956,45 @@ server_lost_client(struct client *c)
 | 
			
		||||
 | 
			
		||||
	close(c->ibuf.fd);
 | 
			
		||||
	imsg_clear(&c->ibuf);
 | 
			
		||||
	xfree(c);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
 | 
			
		||||
		if (ARRAY_ITEM(&dead_clients, i) == NULL) {
 | 
			
		||||
			ARRAY_SET(&dead_clients, i, c);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (i == ARRAY_LENGTH(&dead_clients))
 | 
			
		||||
		ARRAY_ADD(&dead_clients, c);
 | 
			
		||||
	c->flags |= CLIENT_DEAD;
 | 
			
		||||
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Free dead, unreferenced clients and sessions. */
 | 
			
		||||
void
 | 
			
		||||
server_clean_dead(void)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&dead_sessions); i++) {
 | 
			
		||||
		s = ARRAY_ITEM(&dead_sessions, i);
 | 
			
		||||
		if (s == NULL || s->references != 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		ARRAY_SET(&dead_sessions, i, NULL);
 | 
			
		||||
		xfree(s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&dead_clients, i);
 | 
			
		||||
		if (c == NULL || c->references != 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		ARRAY_SET(&dead_clients, i, NULL);
 | 
			
		||||
		xfree(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle window data. */
 | 
			
		||||
void
 | 
			
		||||
server_handle_window(struct window *w, struct window_pane *wp)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user