diff options
-rw-r--r-- | usr.bin/tmux/cmd-wait-for.c | 24 | ||||
-rw-r--r-- | usr.bin/tmux/server.c | 20 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 5 |
3 files changed, 45 insertions, 4 deletions
diff --git a/usr.bin/tmux/cmd-wait-for.c b/usr.bin/tmux/cmd-wait-for.c index a0678f83f8c..ea48a551670 100644 --- a/usr.bin/tmux/cmd-wait-for.c +++ b/usr.bin/tmux/cmd-wait-for.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-wait-for.c,v 1.5 2014/09/01 21:50:18 nicm Exp $ */ +/* $OpenBSD: cmd-wait-for.c,v 1.6 2014/09/01 21:58:41 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net> @@ -194,3 +194,25 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name, return (CMD_RETURN_NORMAL); } +void +cmd_wait_for_flush(void) +{ + struct wait_channel *wc, *wc1; + struct cmd_q *wq, *wq1; + + RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) { + TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) { + TAILQ_REMOVE(&wc->waiters, wq, waitentry); + if (!cmdq_free(wq)) + cmdq_continue(wq); + } + while ((wq = TAILQ_FIRST(&wc->lockers)) != NULL) { + TAILQ_REMOVE(&wc->lockers, wq, waitentry); + if (!cmdq_free(wq)) + cmdq_continue(wq); + } + RB_REMOVE(wait_channels, &wait_channels, wc); + free((void *)wc->name); + free(wc); + } +} diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index 3289dc2196b..51f443873da 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.115 2014/07/21 10:52:48 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.116 2014/09/01 21:58:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -217,16 +217,30 @@ server_loop(void) int server_should_shutdown(void) { - u_int i; + struct client *c; + u_int i; if (!options_get_number(&global_options, "exit-unattached")) { if (!RB_EMPTY(&sessions)) return (0); } + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c != NULL && c->session != NULL) + return (0); + } + + /* + * No attached clients therefore want to exit - flush any waiting + * clients but don't actually exit until they've gone. + */ + cmd_wait_for_flush(); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { if (ARRAY_ITEM(&clients, i) != NULL) return (0); } + return (1); } @@ -238,6 +252,8 @@ server_send_shutdown(void) struct session *s, *next_s; u_int i; + cmd_wait_for_flush(); + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c != NULL) { diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index b6455a6cdd0..8a51d641c57 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.470 2014/09/01 21:50:18 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.471 2014/09/01 21:58:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1924,6 +1924,9 @@ void cmdq_flush(struct cmd_q *); int cmd_string_parse(const char *, struct cmd_list **, const char *, u_int, char **); +/* cmd-wait-for.c */ +void cmd_wait_for_flush(void); + /* client.c */ int client_main(int, char **, int); |