From 6b2129696fbefe44d0adce1f2a11b4ae477cd07e Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Jun 2015 23:27:51 +0000 Subject: Move the nested check from client to server and compare the client tty name to all the pane pty names instead of comparing socket paths. This means that "new -d" will work without unsetting $TMUX. --- server-client.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'server-client.c') diff --git a/server-client.c b/server-client.c index 36408e91..01c8b313 100644 --- a/server-client.c +++ b/server-client.c @@ -46,6 +46,27 @@ void server_client_msg_command(struct client *, struct imsg *); void server_client_msg_identify(struct client *, struct imsg *); void server_client_msg_shell(struct client *); +/* Check if this client is inside this server. */ +int +server_client_check_nested(struct client *c) +{ + struct environ_entry *envent; + struct window_pane *wp; + + if (c->tty.path == NULL) + return (0); + + envent = environ_find(&c->environ, "TMUX"); + if (envent == NULL || *envent->value == '\0') + return (0); + + RB_FOREACH(wp, window_pane_tree, &all_window_panes) { + if (strcmp(wp->tty, c->tty.path) == 0) + return (1); + } + return (0); +} + /* Set client key table. */ void server_client_key_table(struct client *c, const char *name) -- cgit From 8c93b768e4864be330c3d6a7962892135224f0f4 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 5 Jun 2015 18:01:12 +0000 Subject: 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. --- server-client.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'server-client.c') diff --git a/server-client.c b/server-client.c index 01c8b313..b10c1e13 100644 --- a/server-client.c +++ b/server-client.c @@ -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) -- cgit From 10e90ae01f53a67a1b7c3a2c498cefb73c6a23b4 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 5 Jun 2015 18:06:30 +0000 Subject: Change deref to the more sensible unref, and add a couple I missed before. --- server-client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'server-client.c') diff --git a/server-client.c b/server-client.c index b10c1e13..8739b5ab 100644 --- a/server-client.c +++ b/server-client.c @@ -222,7 +222,7 @@ server_client_lost(struct client *c) if (event_initialized(&c->event)) event_del(&c->event); - server_client_deref(c); + server_client_unref(c); server_add_accept(0); /* may be more file descriptors now */ @@ -233,9 +233,9 @@ server_client_lost(struct client *c) /* Remove reference from a client. */ void -server_client_deref(struct client *c) +server_client_unref(struct client *c) { - log_debug("deref client %d (%d references)", c->ibuf.fd, c->references); + log_debug("unref client %d (%d references)", c->ibuf.fd, c->references); c->references--; if (c->references == 0) -- cgit