Change the windows array into an RB tree and fix some places where we
authornicm <nicm@openbsd.org>
Wed, 22 Apr 2015 15:30:11 +0000 (15:30 +0000)
committernicm <nicm@openbsd.org>
Wed, 22 Apr 2015 15:30:11 +0000 (15:30 +0000)
were only looking at the first winlink for a window in a session.

usr.bin/tmux/cmd-set-option.c
usr.bin/tmux/resize.c
usr.bin/tmux/server-client.c
usr.bin/tmux/server-window.c
usr.bin/tmux/server.c
usr.bin/tmux/tmux.h
usr.bin/tmux/window.c

index 6c48a31..f18b5b7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-set-option.c,v 1.71 2014/10/20 22:29:25 nicm Exp $ */
+/* $OpenBSD: cmd-set-option.c,v 1.72 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -176,9 +176,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
 
        /* Start or stop timers when automatic-rename changed. */
        if (strcmp(oe->name, "automatic-rename") == 0) {
-               for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-                       if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                               continue;
+               RB_FOREACH(w, windows, &windows) {
                        if (options_get_number(&w->options, "automatic-rename"))
                                queue_window_name(w);
                        else if (event_initialized(&w->name_timer))
index 8a2dcf6..40f9415 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: resize.c,v 1.14 2014/11/14 02:19:47 nicm Exp $ */
+/* $OpenBSD: resize.c,v 1.15 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,7 +49,7 @@ recalculate_sizes(void)
        struct client           *c;
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i, j, ssx, ssy, has, limit;
+       u_int                    i, ssx, ssy, has, limit;
        int                      flag, has_status, is_zoomed, forced;
 
        RB_FOREACH(s, sessions, &sessions) {
@@ -57,8 +57,8 @@ recalculate_sizes(void)
 
                s->attached = 0;
                ssx = ssy = UINT_MAX;
-               for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
-                       c = ARRAY_ITEM(&clients, j);
+               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+                       c = ARRAY_ITEM(&clients, i);
                        if (c == NULL || c->flags & CLIENT_SUSPENDED)
                                continue;
                        if (c->session == s) {
@@ -92,9 +92,8 @@ recalculate_sizes(void)
                s->sy = ssy;
        }
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL || w->active == NULL)
+       RB_FOREACH(w, windows, &windows) {
+               if (w->active == NULL)
                        continue;
                flag = options_get_number(&w->options, "aggressive-resize");
 
index 78978fc..2582b4b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.133 2015/04/21 15:21:41 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.134 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -720,11 +720,7 @@ server_client_loop(void)
         * Any windows will have been redrawn as part of clients, so clear
         * their flags now. Also check pane focus and resize.
         */
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
-
+       RB_FOREACH(w, windows, &windows) {
                w->flags &= ~WINDOW_REDRAW;
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->fd != -1) {
index 6505e5b..2109d1f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-window.c,v 1.32 2015/03/31 17:45:10 nicm Exp $ */
+/* $OpenBSD: server-window.c,v 1.33 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,24 +34,20 @@ void
 server_window_loop(void)
 {
        struct window   *w;
-       struct winlink  *wl;
        struct session  *s;
-       u_int            i;
-
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
+       struct winlink  *wl;
 
+       RB_FOREACH(w, windows, &windows) {
                RB_FOREACH(s, sessions, &sessions) {
-                       wl = session_has(s, w);
-                       if (wl == NULL)
-                               continue;
-
-                       if (server_window_check_bell(s, wl) ||
-                           server_window_check_activity(s, wl) ||
-                           server_window_check_silence(s, wl))
-                               server_status_session(s);
+                       RB_FOREACH(wl, winlinks, &s->windows) {
+                               if (wl->window != w)
+                                       continue;
+
+                               if (server_window_check_bell(s, wl) ||
+                                   server_window_check_activity(s, wl) ||
+                                   server_window_check_silence(s, wl))
+                                       server_status_session(s);
+                       }
                }
        }
 }
index eaa3507..5d3f4f7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.120 2015/04/22 15:05:03 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.121 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -137,7 +137,7 @@ server_start(int lockfd, char *lockfile)
        logfile("server");
        log_debug("server started, pid %ld", (long) getpid());
 
-       ARRAY_INIT(&windows);
+       RB_INIT(&windows);
        RB_INIT(&all_window_panes);
        ARRAY_INIT(&clients);
        ARRAY_INIT(&dead_clients);
@@ -438,14 +438,11 @@ server_child_signal(void)
 void
 server_child_exited(pid_t pid, int status)
 {
-       struct window           *w;
+       struct window           *w, *w1;
        struct window_pane      *wp;
        struct job              *job;
-       u_int                    i;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
+       RB_FOREACH_SAFE(w, windows, &windows, w1) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->pid == pid) {
                                wp->status = status;
@@ -469,14 +466,11 @@ server_child_stopped(pid_t pid, int status)
 {
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i;
 
        if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU)
                return;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
+       RB_FOREACH(w, windows, &windows) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->pid == pid) {
                                if (killpg(pid, SIGCONT) != 0)
@@ -493,18 +487,13 @@ server_second_callback(unused int fd, unused short events, unused void *arg)
        struct window           *w;
        struct window_pane      *wp;
        struct timeval           tv;
-       u_int                    i;
 
        if (options_get_number(&global_s_options, "lock-server"))
                server_lock_server();
        else
                server_lock_sessions();
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
-
+       RB_FOREACH(w, windows, &windows) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->mode != NULL && wp->mode->timer != NULL)
                                wp->mode->timer(wp);
index dcf2454..2d217c7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.495 2015/04/22 15:05:03 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.496 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -983,8 +983,10 @@ struct window {
        struct options   options;
 
        u_int            references;
+
+       RB_ENTRY(window) entry;
 };
-ARRAY_DECL(windows, struct window *);
+RB_HEAD(windows, window);
 
 /* Entry on local window list. */
 struct winlink {
@@ -2121,6 +2123,8 @@ void       screen_reflow(struct screen *, u_int);
 /* window.c */
 extern struct windows windows;
 extern struct window_pane_tree all_window_panes;
+int             window_cmp(struct window *, struct window *);
+RB_PROTOTYPE(windows, window, entry, window_cmp);
 int             winlink_cmp(struct winlink *, struct winlink *);
 RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
 int             window_pane_cmp(struct window_pane *, struct window_pane *);
index 3492dc3..fc0e869 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window.c,v 1.121 2015/04/22 15:05:03 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.122 2015/04/22 15:30:11 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -64,6 +64,14 @@ void window_pane_error_callback(struct bufferevent *, short, void *);
 
 struct window_pane *window_pane_choose_best(struct window_pane_list *);
 
+RB_GENERATE(windows, window, entry, window_cmp);
+
+int
+window_cmp(struct window *w1, struct window *w2)
+{
+       return (w1->id - w2->id);
+}
+
 RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
 
 int
@@ -248,25 +256,18 @@ winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl)
 struct window *
 window_find_by_id(u_int id)
 {
-       struct window   *w;
-       u_int            i;
+       struct window   w;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w != NULL && w->id == id)
-                       return (w);
-       }
-       return (NULL);
+       w.id = id;
+       return (RB_FIND(windows, &windows, &w));
 }
 
 struct window *
 window_create1(u_int sx, u_int sy)
 {
        struct window   *w;
-       u_int            i;
 
        w = xcalloc(1, sizeof *w);
-       w->id = next_window_id++;
        w->name = NULL;
        w->flags = 0;
 
@@ -283,16 +284,11 @@ window_create1(u_int sx, u_int sy)
        if (options_get_number(&w->options, "automatic-rename"))
                queue_window_name(w);
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if (ARRAY_ITEM(&windows, i) == NULL) {
-                       ARRAY_SET(&windows, i, w);
-                       break;
-               }
-       }
-       if (i == ARRAY_LENGTH(&windows))
-               ARRAY_ADD(&windows, w);
        w->references = 0;
 
+       w->id = next_window_id++;
+       RB_INSERT (windows, &windows, w);
+
        return (w);
 }
 
@@ -327,19 +323,9 @@ window_create(const char *name, int argc, char **argv, const char *path,
 void
 window_destroy(struct window *w)
 {
-       u_int   i;
-
        window_unzoom(w);
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if (w == ARRAY_ITEM(&windows, i))
-                       break;
-       }
-       if (i == ARRAY_LENGTH(&windows))
-               fatalx("index not found");
-       ARRAY_SET(&windows, i, NULL);
-       while (!ARRAY_EMPTY(&windows) && ARRAY_LAST(&windows) == NULL)
-               ARRAY_TRUNC(&windows, 1);
+       RB_REMOVE(windows, &windows, w);
 
        if (w->layout_root != NULL)
                layout_free(w);
@@ -1328,26 +1314,18 @@ window_pane_find_right(struct window_pane *wp)
 void
 winlink_clear_flags(struct winlink *wl)
 {
-       struct winlink  *wm;
        struct session  *s;
-       struct window   *w;
-       u_int            i;
-
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
-
-               RB_FOREACH(s, sessions, &sessions) {
-                       if ((wm = session_has(s, w)) == NULL)
-                               continue;
+       struct winlink  *wl_loop;
 
-                       if (wm->window != wl->window)
+       RB_FOREACH(s, sessions, &sessions) {
+               RB_FOREACH(wl_loop, winlinks, &s->windows) {
+                       if (wl_loop->window != wl->window)
                                continue;
-                       if ((wm->flags & WINLINK_ALERTFLAGS) == 0)
+                       if ((wl_loop->flags & WINLINK_ALERTFLAGS) == 0)
                                continue;
 
-                       wm->flags &= ~WINLINK_ALERTFLAGS;
-                       wm->window->flags &= ~WINDOW_ALERTFLAGS;
+                       wl_loop->flags &= ~WINLINK_ALERTFLAGS;
+                       wl_loop->window->flags &= ~WINDOW_ALERTFLAGS;
                        server_status_session(s);
                }
        }