From 58e8e0eac841d6d337de3da4e2f81665c3cd3faa Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 21 Aug 2012 10:00:33 +0000 Subject: [PATCH] Fix up window reference counting and don't crash if the rename timer fires while the window is dead but still referenced. Fixes problem reported by Michael Scholz. --- names.c | 3 +++ notify.c | 3 ++- tmux.h | 1 + window.c | 19 ++++++++++++------- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/names.c b/names.c index de4b30cc..46708bce 100644 --- a/names.c +++ b/names.c @@ -50,6 +50,9 @@ window_name_callback(unused int fd, unused short events, void *data) struct window *w = data; char *name, *wname; + if (w->active == NULL) + return; + if (!options_get_number(&w->options, "automatic-rename")) { if (event_initialized(&w->name_timer)) event_del(&w->name_timer); diff --git a/notify.c b/notify.c index dad50b94..33fea56c 100644 --- a/notify.c +++ b/notify.c @@ -125,7 +125,8 @@ notify_drain(void) if (ne->session != NULL) ne->session->references--; if (ne->window != NULL) - ne->window->references--; + window_remove_ref(ne->window); + TAILQ_REMOVE(¬ify_queue, ne, entry); free(ne); } diff --git a/tmux.h b/tmux.h index 10d4f03d..449f0676 100644 --- a/tmux.h +++ b/tmux.h @@ -2130,6 +2130,7 @@ struct window_pane *window_pane_find_down(struct window_pane *); struct window_pane *window_pane_find_left(struct window_pane *); struct window_pane *window_pane_find_right(struct window_pane *); void window_set_name(struct window *, const char *); +void window_remove_ref(struct window *); void winlink_clear_flags(struct winlink *); void window_mode_attrs(struct grid_cell *, struct options *); diff --git a/window.c b/window.c index dcf1dd04..71225a9b 100644 --- a/window.c +++ b/window.c @@ -182,13 +182,8 @@ winlink_remove(struct winlinks *wwl, struct winlink *wl) free(wl->status_text); free(wl); - if (w != NULL) { - if (w->references == 0) - fatal("bad reference count"); - w->references--; - if (w->references == 0) - window_destroy(w); - } + if (w != NULL) + window_remove_ref(w); } struct winlink * @@ -362,6 +357,16 @@ window_destroy(struct window *w) free(w); } +void +window_remove_ref(struct window *w) +{ + if (w->references == 0) + fatal("bad reference count"); + w->references--; + if (w->references == 0) + window_destroy(w); +} + void window_set_name(struct window *w, const char *new_name) {