Convert clients list into a TAILQ.

This commit is contained in:
nicm 2015-04-24 23:17:11 +00:00
parent 583b4ab72b
commit aeedb464a6
15 changed files with 118 additions and 223 deletions

View File

@ -51,7 +51,6 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
struct window_pane *wp = NULL; struct window_pane *wp = NULL;
const char *update; const char *update;
char *cause; char *cause;
u_int i;
int fd; int fd;
struct format_tree *ft; struct format_tree *ft;
char *cp; char *cp;
@ -92,11 +91,8 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
* Can't use server_write_session in case attaching to * Can't use server_write_session in case attaching to
* the same session as currently attached to. * the same session as currently attached to.
*/ */
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != s || c == cmdq->client)
if (c == NULL || c->session != s)
continue;
if (c == cmdq->client)
continue; continue;
server_write_client(c, MSG_DETACH, server_write_client(c, MSG_DETACH,
c->session->name, c->session->name,

View File

@ -59,7 +59,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl; struct winlink *wl;
const char *template; const char *template;
char *action; char *action;
u_int i, idx, cur; u_int idx, cur;
if ((c = cmd_current_client(cmdq)) == NULL) { if ((c = cmd_current_client(cmdq)) == NULL) {
cmdq_error(cmdq, "no client available"); cmdq_error(cmdq, "no client available");
@ -81,24 +81,24 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
action = xstrdup("detach-client -t '%%'"); action = xstrdup("detach-client -t '%%'");
cur = idx = 0; cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c1, &clients, entry) {
c1 = ARRAY_ITEM(&clients, i); if (c1->session == NULL || c1->tty.path == NULL)
if (c1 == NULL || c1->session == NULL || c1->tty.path == NULL)
continue; continue;
if (c1 == cmdq->client) if (c1 == cmdq->client)
cur = idx; cur = idx;
idx++;
cdata = window_choose_data_create(TREE_OTHER, c, c->session); cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = i; cdata->idx = idx;
cdata->ft_template = xstrdup(template); cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", i); format_add(cdata->ft, "line", "%u", idx);
format_defaults(cdata->ft, c1, NULL, NULL, NULL); format_defaults(cdata->ft, c1, NULL, NULL, NULL);
cdata->command = cmd_template_replace(action, c1->tty.path, 1); cdata->command = cmd_template_replace(action, c1->tty.path, 1);
window_choose_add(wl->window->active, cdata); window_choose_add(wl->window->active, cdata);
idx++;
} }
free(action); free(action);
@ -112,15 +112,19 @@ void
cmd_choose_client_callback(struct window_choose_data *cdata) cmd_choose_client_callback(struct window_choose_data *cdata)
{ {
struct client *c; struct client *c;
u_int idx;
if (cdata == NULL) if (cdata == NULL)
return; return;
if (cdata->start_client->flags & CLIENT_DEAD) if (cdata->start_client->flags & CLIENT_DEAD)
return; return;
if (cdata->idx > ARRAY_LENGTH(&clients) - 1) idx = 0;
return; TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, cdata->idx); if (idx == cdata->idx)
break;
idx++;
}
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
return; return;

View File

@ -51,7 +51,6 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c, *cloop; struct client *c, *cloop;
struct session *s; struct session *s;
enum msgtype msgtype; enum msgtype msgtype;
u_int i;
if (self->entry == &cmd_suspend_client_entry) { if (self->entry == &cmd_suspend_client_entry) {
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
@ -72,9 +71,8 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
if (s == NULL) if (s == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(cloop, &clients, entry) {
cloop = ARRAY_ITEM(&clients, i); if (cloop->session != s)
if (cloop == NULL || cloop->session != s)
continue; continue;
server_write_client(cloop, msgtype, server_write_client(cloop, msgtype,
cloop->session->name, cloop->session->name,
@ -88,11 +86,8 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) { if (args_has(args, 'a')) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(cloop, &clients, entry) {
cloop = ARRAY_ITEM(&clients, i); if (cloop->session == NULL || cloop == c)
if (cloop == NULL || cloop->session == NULL)
continue;
if (cloop == c)
continue; continue;
server_write_client(cloop, msgtype, server_write_client(cloop, msgtype,
cloop->session->name, cloop->session->name,

View File

@ -51,7 +51,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s; struct session *s;
struct format_tree *ft; struct format_tree *ft;
const char *template; const char *template;
u_int i; u_int idx;
char *line; char *line;
if (args_has(args, 't')) { if (args_has(args, 't')) {
@ -64,16 +64,13 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = LIST_CLIENTS_TEMPLATE; template = LIST_CLIENTS_TEMPLATE;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { idx = 0;
c = ARRAY_ITEM(&clients, i); TAILQ_FOREACH(c, &clients, entry) {
if (c == NULL || c->session == NULL) if (c->session == NULL || (s != NULL && s != c->session))
continue;
if (s != NULL && s != c->session)
continue; continue;
ft = format_create(); ft = format_create();
format_add(ft, "line", "%u", i); format_add(ft, "line", "%u", idx);
format_defaults(ft, c, NULL, NULL, NULL); format_defaults(ft, c, NULL, NULL, NULL);
line = format_expand(ft, template); line = format_expand(ft, template);
@ -81,6 +78,8 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
free(line); free(line);
format_free(ft); format_free(ft);
idx++;
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@ -91,7 +91,6 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
struct options *oo; struct options *oo;
struct window *w; struct window *w;
const char *optstr, *valstr; const char *optstr, *valstr;
u_int i;
/* Get the option name and value. */ /* Get the option name and value. */
optstr = args->argv[0]; optstr = args->argv[0];
@ -186,9 +185,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
/* Update sizes and redraw. May not need it but meh. */ /* Update sizes and redraw. May not need it but meh. */
recalculate_sizes(); recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL)
if (c != NULL && c->session != NULL)
server_redraw_client(c); server_redraw_client(c);
} }

26
cmd.c
View File

@ -116,10 +116,12 @@ const struct cmd_entry *cmd_table[] = {
NULL NULL
}; };
ARRAY_DECL(client_list, struct client *);
int cmd_session_better(struct session *, struct session *, int); int cmd_session_better(struct session *, struct session *, int);
struct session *cmd_choose_session_list(struct sessionslist *); struct session *cmd_choose_session_list(struct sessionslist *);
struct session *cmd_choose_session(int); struct session *cmd_choose_session(int);
struct client *cmd_choose_client(struct clients *); struct client *cmd_choose_client(struct client_list *);
struct client *cmd_lookup_client(const char *); struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(struct cmd_q *, const char *, int *); struct session *cmd_lookup_session(struct cmd_q *, const char *, int *);
struct session *cmd_lookup_session_id(const char *); struct session *cmd_lookup_session_id(const char *);
@ -452,8 +454,7 @@ cmd_current_client(struct cmd_q *cmdq)
{ {
struct session *s; struct session *s;
struct client *c; struct client *c;
struct clients cc; struct client_list cc;
u_int i;
if (cmdq->client != NULL && cmdq->client->session != NULL) if (cmdq->client != NULL && cmdq->client->session != NULL)
return (cmdq->client); return (cmdq->client);
@ -465,9 +466,7 @@ cmd_current_client(struct cmd_q *cmdq)
s = cmd_current_session(cmdq, 0); s = cmd_current_session(cmdq, 0);
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) { if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
ARRAY_INIT(&cc); ARRAY_INIT(&cc);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
if (s == c->session) if (s == c->session)
ARRAY_ADD(&cc, c); ARRAY_ADD(&cc, c);
} }
@ -478,12 +477,17 @@ cmd_current_client(struct cmd_q *cmdq)
return (c); return (c);
} }
return (cmd_choose_client(&clients)); ARRAY_INIT(&cc);
TAILQ_FOREACH(c, &clients, entry)
ARRAY_ADD(&cc, c);
c = cmd_choose_client(&cc);
ARRAY_FREE(&cc);
return (c);
} }
/* Choose the most recently used client from a list. */ /* Choose the most recently used client from a list. */
struct client * struct client *
cmd_choose_client(struct clients *cc) cmd_choose_client(struct client_list *cc)
{ {
struct client *c, *cbest; struct client *c, *cbest;
struct timeval *tv = NULL; struct timeval *tv = NULL;
@ -615,11 +619,9 @@ cmd_lookup_client(const char *name)
{ {
struct client *c; struct client *c;
const char *path; const char *path;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == NULL || c->tty.path == NULL)
if (c == NULL || c->session == NULL || c->tty.path == NULL)
continue; continue;
path = c->tty.path; path = c->tty.path;

View File

@ -64,11 +64,9 @@ control_notify_window_layout_changed(struct window *w)
struct session *s; struct session *s;
struct format_tree *ft; struct format_tree *ft;
struct winlink *wl; struct winlink *wl;
u_int i;
const char *template; const char *template;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
continue; continue;
s = c->session; s = c->session;
@ -100,10 +98,8 @@ control_notify_window_unlinked(unused struct session *s, struct window *w)
{ {
struct client *c; struct client *c;
struct session *cs; struct session *cs;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
continue; continue;
cs = c->session; cs = c->session;
@ -120,10 +116,8 @@ control_notify_window_linked(unused struct session *s, struct window *w)
{ {
struct client *c; struct client *c;
struct session *cs; struct session *cs;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
continue; continue;
cs = c->session; cs = c->session;
@ -140,10 +134,8 @@ control_notify_window_renamed(struct window *w)
{ {
struct client *c; struct client *c;
struct session *cs; struct session *cs;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
continue; continue;
cs = c->session; cs = c->session;
@ -174,10 +166,8 @@ void
control_notify_session_renamed(struct session *s) control_notify_session_renamed(struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c)) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
continue; continue;
@ -189,10 +179,8 @@ void
control_notify_session_created(unused struct session *s) control_notify_session_created(unused struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c)) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
continue; continue;
@ -204,10 +192,8 @@ void
control_notify_session_close(unused struct session *s) control_notify_session_close(unused struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c)) if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
continue; continue;

View File

@ -136,7 +136,6 @@ void
notify_input(struct window_pane *wp, struct evbuffer *input) notify_input(struct window_pane *wp, struct evbuffer *input)
{ {
struct client *c; struct client *c;
u_int i;
/* /*
* notify_input() is not queued and only does anything when * notify_input() is not queued and only does anything when
@ -145,9 +144,8 @@ notify_input(struct window_pane *wp, struct evbuffer *input)
if (!notify_enabled) if (!notify_enabled)
return; return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->flags & CLIENT_CONTROL)
if (c != NULL && (c->flags & CLIENT_CONTROL))
control_notify_input(c, wp, input); control_notify_input(c, wp, input);
} }
} }

View File

@ -49,7 +49,7 @@ recalculate_sizes(void)
struct client *c; struct client *c;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
u_int i, ssx, ssy, has, limit; u_int ssx, ssy, has, limit;
int flag, has_status, is_zoomed, forced; int flag, has_status, is_zoomed, forced;
RB_FOREACH(s, sessions, &sessions) { RB_FOREACH(s, sessions, &sessions) {
@ -57,9 +57,8 @@ recalculate_sizes(void)
s->attached = 0; s->attached = 0;
ssx = ssy = UINT_MAX; ssx = ssy = UINT_MAX;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->flags & CLIENT_SUSPENDED)
if (c == NULL || c->flags & CLIENT_SUSPENDED)
continue; continue;
if (c->session == s) { if (c->session == s) {
if (c->tty.sx < ssx) if (c->tty.sx < ssx)

View File

@ -60,7 +60,6 @@ void
server_client_create(int fd) server_client_create(int fd)
{ {
struct client *c; struct client *c;
u_int i;
setblocking(fd, 0); setblocking(fd, 0);
@ -108,13 +107,7 @@ server_client_create(int fd)
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_INSERT_TAIL(&clients, c, entry);
if (ARRAY_ITEM(&clients, i) == NULL) {
ARRAY_SET(&clients, i, c);
return;
}
}
ARRAY_ADD(&clients, c);
log_debug("new client %d", fd); log_debug("new client %d", fd);
} }
@ -148,10 +141,7 @@ server_client_lost(struct client *c)
struct message_entry *msg; struct message_entry *msg;
u_int i; u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_REMOVE(&clients, c, entry);
if (ARRAY_ITEM(&clients, i) == c)
ARRAY_SET(&clients, i, NULL);
}
log_debug("lost client %d", c->ibuf.fd); log_debug("lost client %d", c->ibuf.fd);
/* /*
@ -205,14 +195,7 @@ server_client_lost(struct client *c)
if (event_initialized(&c->event)) if (event_initialized(&c->event))
event_del(&c->event); event_del(&c->event);
for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) { TAILQ_INSERT_TAIL(&dead_clients, c, entry);
if (ARRAY_ITEM(&dead_clients, i) == NULL) {
ARRAY_SET(&dead_clients, i, c);
break;
}
}
if (i == ARRAY_LENGTH(&dead_clients))
ARRAY_ADD(&dead_clients, c);
c->flags |= CLIENT_DEAD; c->flags |= CLIENT_DEAD;
server_add_accept(0); /* may be more file descriptors now */ server_add_accept(0); /* may be more file descriptors now */
@ -263,16 +246,14 @@ server_client_status_timer(void)
struct client *c; struct client *c;
struct session *s; struct session *s;
struct timeval tv; struct timeval tv;
u_int i;
int interval; int interval;
time_t difference; time_t difference;
if (gettimeofday(&tv, NULL) != 0) if (gettimeofday(&tv, NULL) != 0)
fatal("gettimeofday failed"); fatal("gettimeofday failed");
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == NULL)
if (c == NULL || c->session == NULL)
continue; continue;
if (c->message_string != NULL || c->prompt_string != NULL) { if (c->message_string != NULL || c->prompt_string != NULL) {
/* /*
@ -702,13 +683,8 @@ server_client_loop(void)
struct client *c; struct client *c;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL)
continue;
TAILQ_FOREACH(c, &clients, entry) {
server_client_check_exit(c); server_client_check_exit(c);
if (c->session != NULL) { if (c->session != NULL) {
server_client_check_redraw(c); server_client_check_redraw(c);
@ -755,7 +731,6 @@ server_client_check_resize(struct window_pane *wp)
void void
server_client_check_focus(struct window_pane *wp) server_client_check_focus(struct window_pane *wp)
{ {
u_int i;
struct client *c; struct client *c;
int push; int push;
@ -783,12 +758,8 @@ server_client_check_focus(struct window_pane *wp)
* If our window is the current window in any focused clients with an * If our window is the current window in any focused clients with an
* attached session, we're focused. * attached session, we're focused.
*/ */
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == NULL || !(c->flags & CLIENT_FOCUSED))
if (c == NULL || c->session == NULL)
continue;
if (!(c->flags & CLIENT_FOCUSED))
continue; continue;
if (c->session->flags & SESSION_UNATTACHED) if (c->session->flags & SESSION_UNATTACHED)
continue; continue;

View File

@ -77,12 +77,8 @@ server_write_session(struct session *s, enum msgtype type, const void *buf,
size_t len) size_t len)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session == s) if (c->session == s)
server_write_client(c, type, buf, len); server_write_client(c, type, buf, len);
} }
@ -104,12 +100,8 @@ void
server_redraw_session(struct session *s) server_redraw_session(struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session == s) if (c->session == s)
server_redraw_client(c); server_redraw_client(c);
} }
@ -132,12 +124,8 @@ void
server_status_session(struct session *s) server_status_session(struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session == s) if (c->session == s)
server_status_client(c); server_status_client(c);
} }
@ -160,13 +148,9 @@ void
server_redraw_window(struct window *w) server_redraw_window(struct window *w)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL && c->session->curw->window == w)
if (c == NULL || c->session == NULL)
continue;
if (c->session->curw->window == w)
server_redraw_client(c); server_redraw_client(c);
} }
w->flags |= WINDOW_REDRAW; w->flags |= WINDOW_REDRAW;
@ -176,13 +160,9 @@ void
server_redraw_window_borders(struct window *w) server_redraw_window_borders(struct window *w)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL && c->session->curw->window == w)
if (c == NULL || c->session == NULL)
continue;
if (c->session->curw->window == w)
c->flags |= CLIENT_BORDERS; c->flags |= CLIENT_BORDERS;
} }
} }
@ -208,13 +188,10 @@ void
server_lock(void) server_lock(void)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL)
if (c == NULL || c->session == NULL) server_lock_client(c);
continue;
server_lock_client(c);
} }
} }
@ -222,13 +199,10 @@ void
server_lock_session(struct session *s) server_lock_session(struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == s)
if (c == NULL || c->session == NULL || c->session != s) server_lock_client(c);
continue;
server_lock_client(c);
} }
} }
@ -430,16 +404,14 @@ server_destroy_session(struct session *s)
{ {
struct client *c; struct client *c;
struct session *s_new; struct session *s_new;
u_int i;
if (!options_get_number(&s->options, "detach-on-destroy")) if (!options_get_number(&s->options, "detach-on-destroy"))
s_new = server_next_session(s); s_new = server_next_session(s);
else else
s_new = NULL; s_new = NULL;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != s)
if (c == NULL || c->session != s)
continue; continue;
if (s_new == NULL) { if (s_new == NULL) {
c->session = NULL; c->session = NULL;

View File

@ -58,7 +58,6 @@ server_window_check_bell(struct session *s, struct winlink *wl)
{ {
struct client *c; struct client *c;
struct window *w = wl->window; struct window *w = wl->window;
u_int i;
int action, visual; int action, visual;
if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL) if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
@ -74,9 +73,8 @@ server_window_check_bell(struct session *s, struct winlink *wl)
action = options_get_number(&s->options, "bell-action"); action = options_get_number(&s->options, "bell-action");
if (action == BELL_NONE) if (action == BELL_NONE)
return (0); return (0);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != s || c->flags & CLIENT_CONTROL)
if (c == NULL || c->session != s || c->flags & CLIENT_CONTROL)
continue; continue;
if (!visual) { if (!visual) {
if (c->session->curw->window == w || action == BELL_ANY) if (c->session->curw->window == w || action == BELL_ANY)
@ -98,7 +96,6 @@ server_window_check_activity(struct session *s, struct winlink *wl)
{ {
struct client *c; struct client *c;
struct window *w = wl->window; struct window *w = wl->window;
u_int i;
if (s->curw->window == w) if (s->curw->window == w)
w->flags &= ~WINDOW_ACTIVITY; w->flags &= ~WINDOW_ACTIVITY;
@ -116,9 +113,8 @@ server_window_check_activity(struct session *s, struct winlink *wl)
wl->flags |= WINLINK_ACTIVITY; wl->flags |= WINLINK_ACTIVITY;
if (options_get_number(&s->options, "visual-activity")) { if (options_get_number(&s->options, "visual-activity")) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != s)
if (c == NULL || c->session != s)
continue; continue;
status_message_set(c, "Activity in window %d", wl->idx); status_message_set(c, "Activity in window %d", wl->idx);
} }
@ -134,7 +130,6 @@ server_window_check_silence(struct session *s, struct winlink *wl)
struct client *c; struct client *c;
struct window *w = wl->window; struct window *w = wl->window;
struct timeval timer; struct timeval timer;
u_int i;
int silence_interval, timer_difference; int silence_interval, timer_difference;
if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE) if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
@ -167,9 +162,8 @@ server_window_check_silence(struct session *s, struct winlink *wl)
wl->flags |= WINLINK_SILENCE; wl->flags |= WINLINK_SILENCE;
if (options_get_number(&s->options, "visual-silence")) { if (options_get_number(&s->options, "visual-silence")) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != s)
if (c == NULL || c->session != s)
continue; continue;
status_message_set(c, "Silence in window %d", wl->idx); status_message_set(c, "Silence in window %d", wl->idx);
} }
@ -183,11 +177,9 @@ void
ring_bell(struct session *s) ring_bell(struct session *s)
{ {
struct client *c; struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == s && !(c->flags & CLIENT_CONTROL))
if (c != NULL && c->session == s && !(c->flags & CLIENT_CONTROL))
tty_bell(&c->tty); tty_bell(&c->tty);
} }
} }

View File

@ -139,8 +139,8 @@ server_start(int lockfd, char *lockfile)
RB_INIT(&windows); RB_INIT(&windows);
RB_INIT(&all_window_panes); RB_INIT(&all_window_panes);
ARRAY_INIT(&clients); TAILQ_INIT(&clients);
ARRAY_INIT(&dead_clients); TAILQ_INIT(&dead_clients);
RB_INIT(&sessions); RB_INIT(&sessions);
RB_INIT(&dead_sessions); RB_INIT(&dead_sessions);
TAILQ_INIT(&session_groups); TAILQ_INIT(&session_groups);
@ -166,7 +166,7 @@ server_start(int lockfd, char *lockfile)
cfg_cmd_q->emptyfn = cfg_default_done; cfg_cmd_q->emptyfn = cfg_default_done;
cfg_finished = 0; cfg_finished = 0;
cfg_references = 1; cfg_references = 1;
cfg_client = ARRAY_FIRST(&clients); cfg_client = TAILQ_FIRST(&clients);
if (cfg_client != NULL) if (cfg_client != NULL)
cfg_client->references++; cfg_client->references++;
@ -212,16 +212,14 @@ int
server_should_shutdown(void) server_should_shutdown(void)
{ {
struct client *c; struct client *c;
u_int i;
if (!options_get_number(&global_options, "exit-unattached")) { if (!options_get_number(&global_options, "exit-unattached")) {
if (!RB_EMPTY(&sessions)) if (!RB_EMPTY(&sessions))
return (0); return (0);
} }
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL)
if (c != NULL && c->session != NULL)
return (0); return (0);
} }
@ -230,10 +228,8 @@ server_should_shutdown(void)
* clients but don't actually exit until they've gone. * clients but don't actually exit until they've gone.
*/ */
cmd_wait_for_flush(); cmd_wait_for_flush();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { if (!TAILQ_EMPTY(&clients))
if (ARRAY_ITEM(&clients, i) != NULL) return (0);
return (0);
}
return (1); return (1);
} }
@ -242,55 +238,42 @@ server_should_shutdown(void)
void void
server_send_shutdown(void) server_send_shutdown(void)
{ {
struct client *c; struct client *c, *c1;
struct session *s, *next_s; struct session *s, *s1;
u_int i;
cmd_wait_for_flush(); cmd_wait_for_flush();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
c = ARRAY_ITEM(&clients, i); if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
if (c != NULL) { server_client_lost(c);
if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED)) else
server_client_lost(c); server_write_client(c, MSG_SHUTDOWN, NULL, 0);
else c->session = NULL;
server_write_client(c, MSG_SHUTDOWN, NULL, 0);
c->session = NULL;
}
} }
s = RB_MIN(sessions, &sessions); RB_FOREACH_SAFE(s, sessions, &sessions, s1)
while (s != NULL) {
next_s = RB_NEXT(sessions, &sessions, s);
session_destroy(s); session_destroy(s);
s = next_s;
}
} }
/* Free dead, unreferenced clients and sessions. */ /* Free dead, unreferenced clients and sessions. */
void void
server_clean_dead(void) server_clean_dead(void)
{ {
struct session *s, *next_s; struct session *s, *s1;
struct client *c; struct client *c, *c1;
u_int i;
s = RB_MIN(sessions, &dead_sessions); RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) {
while (s != NULL) { if (s->references != 0)
next_s = RB_NEXT(sessions, &dead_sessions, s); continue;
if (s->references == 0) { RB_REMOVE(sessions, &dead_sessions, s);
RB_REMOVE(sessions, &dead_sessions, s); free(s->name);
free(s->name); free(s);
free(s);
}
s = next_s;
} }
for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) { TAILQ_FOREACH_SAFE(c, &dead_clients, entry, c1) {
c = ARRAY_ITEM(&dead_clients, i); if (c->references != 0)
if (c == NULL || c->references != 0)
continue; continue;
ARRAY_SET(&dead_clients, i, NULL); TAILQ_REMOVE(&dead_clients, c, entry);
free(c); free(c);
} }
} }

4
tmux.h
View File

@ -1349,8 +1349,10 @@ struct client {
struct cmd_q *cmdq; struct cmd_q *cmdq;
int references; int references;
TAILQ_ENTRY(client) entry;
}; };
ARRAY_DECL(clients, struct client *); TAILQ_HEAD(clients, client);
/* Parsed arguments structures. */ /* Parsed arguments structures. */
struct args_entry { struct args_entry {

6
tty.c
View File

@ -708,7 +708,6 @@ tty_write(
{ {
struct window_pane *wp = ctx->wp; struct window_pane *wp = ctx->wp;
struct client *c; struct client *c;
u_int i;
/* wp can be NULL if updating the screen but not the terminal. */ /* wp can be NULL if updating the screen but not the terminal. */
if (wp == NULL) if (wp == NULL)
@ -719,9 +718,8 @@ tty_write(
if (!window_pane_visible(wp) || wp->flags & PANE_DROP) if (!window_pane_visible(wp) || wp->flags & PANE_DROP)
return; return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session == NULL || c->tty.term == NULL)
if (c == NULL || c->session == NULL || c->tty.term == NULL)
continue; continue;
if (c->flags & CLIENT_SUSPENDED) if (c->flags & CLIENT_SUSPENDED)
continue; continue;