mirror of
https://github.com/tmux/tmux.git
synced 2025-01-14 20:58:53 +00:00
Instead of putting dead clients on a list and checking it every loop,
use event_once to queue a callback to deal with them. Also dead clients with references would never actually be freed because the wrap-up functions (the callback for stdin, or status_prompt_clear) would never be called. So call them in server_client_lost.
This commit is contained in:
parent
b0782df8a6
commit
8c93b768e4
@ -117,7 +117,7 @@ cmd_confirm_before_free(void *data)
|
||||
struct cmd_confirm_before_data *cdata = data;
|
||||
struct client *c = cdata->client;
|
||||
|
||||
c->references--;
|
||||
server_client_deref(c);
|
||||
|
||||
free(cdata->cmd);
|
||||
free(cdata);
|
||||
|
@ -132,7 +132,7 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
||||
return;
|
||||
c->stdin_callback = NULL;
|
||||
|
||||
c->references--;
|
||||
server_client_deref(c);
|
||||
if (c->flags & CLIENT_DEAD)
|
||||
return;
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "tmux.h"
|
||||
|
||||
void server_client_key_table(struct client *, const char *);
|
||||
void server_client_free(int, short, void *);
|
||||
void server_client_check_focus(struct window_pane *);
|
||||
void server_client_check_resize(struct window_pane *);
|
||||
int server_client_check_mouse(struct client *);
|
||||
@ -85,7 +86,7 @@ server_client_create(int fd)
|
||||
setblocking(fd, 0);
|
||||
|
||||
c = xcalloc(1, sizeof *c);
|
||||
c->references = 0;
|
||||
c->references = 1;
|
||||
imsg_init(&c->ibuf, fd);
|
||||
server_update_event(c);
|
||||
|
||||
@ -161,6 +162,14 @@ server_client_lost(struct client *c)
|
||||
{
|
||||
struct message_entry *msg, *msg1;
|
||||
|
||||
c->flags |= CLIENT_DEAD;
|
||||
|
||||
status_prompt_clear(c);
|
||||
status_message_clear(c);
|
||||
|
||||
if (c->stdin_callback != NULL)
|
||||
c->stdin_callback(c, 1, c->stdin_callback_data);
|
||||
|
||||
TAILQ_REMOVE(&clients, c, entry);
|
||||
log_debug("lost client %d", c->ibuf.fd);
|
||||
|
||||
@ -213,8 +222,7 @@ server_client_lost(struct client *c)
|
||||
if (event_initialized(&c->event))
|
||||
event_del(&c->event);
|
||||
|
||||
TAILQ_INSERT_TAIL(&dead_clients, c, entry);
|
||||
c->flags |= CLIENT_DEAD;
|
||||
server_client_deref(c);
|
||||
|
||||
server_add_accept(0); /* may be more file descriptors now */
|
||||
|
||||
@ -223,6 +231,29 @@ server_client_lost(struct client *c)
|
||||
server_update_socket();
|
||||
}
|
||||
|
||||
/* Remove reference from a client. */
|
||||
void
|
||||
server_client_deref(struct client *c)
|
||||
{
|
||||
log_debug("deref client %d (%d references)", c->ibuf.fd, c->references);
|
||||
|
||||
c->references--;
|
||||
if (c->references == 0)
|
||||
event_once(-1, EV_TIMEOUT, server_client_free, c, NULL);
|
||||
}
|
||||
|
||||
/* Free dead client. */
|
||||
void
|
||||
server_client_free(unused int fd, unused short events, void *arg)
|
||||
{
|
||||
struct client *c = arg;
|
||||
|
||||
log_debug("free client %d (%d references)", c->ibuf.fd, c->references);
|
||||
|
||||
if (c->references == 0)
|
||||
free(c);
|
||||
}
|
||||
|
||||
/* Process a single client event. */
|
||||
void
|
||||
server_client_callback(int fd, short events, void *data)
|
||||
|
11
server.c
11
server.c
@ -41,9 +41,7 @@
|
||||
* Main server functions.
|
||||
*/
|
||||
|
||||
/* Client list. */
|
||||
struct clients clients;
|
||||
struct clients dead_clients;
|
||||
|
||||
int server_fd;
|
||||
int server_shutdown;
|
||||
@ -205,7 +203,6 @@ server_start(int lockfd, char *lockfile)
|
||||
RB_INIT(&windows);
|
||||
RB_INIT(&all_window_panes);
|
||||
TAILQ_INIT(&clients);
|
||||
TAILQ_INIT(&dead_clients);
|
||||
RB_INIT(&sessions);
|
||||
RB_INIT(&dead_sessions);
|
||||
TAILQ_INIT(&session_groups);
|
||||
@ -325,7 +322,6 @@ void
|
||||
server_clean_dead(void)
|
||||
{
|
||||
struct session *s, *s1;
|
||||
struct client *c, *c1;
|
||||
|
||||
RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) {
|
||||
if (s->references != 0)
|
||||
@ -334,13 +330,6 @@ server_clean_dead(void)
|
||||
free(s->name);
|
||||
free(s);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(c, &dead_clients, entry, c1) {
|
||||
if (c->references != 0)
|
||||
continue;
|
||||
TAILQ_REMOVE(&dead_clients, c, entry);
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update socket execute permissions based on whether sessions are attached. */
|
||||
|
1
tmux.h
1
tmux.h
@ -1871,6 +1871,7 @@ int server_client_check_nested(struct client *);
|
||||
void server_client_handle_key(struct client *, int);
|
||||
void server_client_create(int);
|
||||
int server_client_open(struct client *, char **);
|
||||
void server_client_deref(struct client *);
|
||||
void server_client_lost(struct client *);
|
||||
void server_client_callback(int, short, void *);
|
||||
void server_client_status_timer(void);
|
||||
|
Loading…
Reference in New Issue
Block a user