From: nicm Date: Fri, 5 Jun 2015 18:01:12 +0000 (+0000) Subject: Instead of putting dead clients on a list and checking it every loop, X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=629b6251a086286bb3aa5f2f4f529a33980d28a7;p=openbsd 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. --- diff --git a/usr.bin/tmux/cmd-confirm-before.c b/usr.bin/tmux/cmd-confirm-before.c index 4a53398ead9..5d29087b3ae 100644 --- a/usr.bin/tmux/cmd-confirm-before.c +++ b/usr.bin/tmux/cmd-confirm-before.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-confirm-before.c,v 1.23 2015/04/19 21:34:21 nicm Exp $ */ +/* $OpenBSD: cmd-confirm-before.c,v 1.24 2015/06/05 18:01:12 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha @@ -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); diff --git a/usr.bin/tmux/cmd-load-buffer.c b/usr.bin/tmux/cmd-load-buffer.c index 161c554896b..da0846cac17 100644 --- a/usr.bin/tmux/cmd-load-buffer.c +++ b/usr.bin/tmux/cmd-load-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-load-buffer.c,v 1.32 2015/04/27 16:25:57 nicm Exp $ */ +/* $OpenBSD: cmd-load-buffer.c,v 1.33 2015/06/05 18:01:12 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha @@ -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; diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index e551c41ca9b..c9232bd65a4 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.140 2015/06/04 23:27:51 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.141 2015/06/05 18:01:12 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -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) diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index 98cecda9379..4f157fdc175 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.126 2015/06/04 11:43:51 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.127 2015/06/05 18:01:12 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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. */ diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 2af070f295b..148c2dd8a58 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.517 2015/06/04 23:27:51 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.518 2015/06/05 18:01:12 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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);