Update of /cvsroot/tmux/tmux
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv31151

Modified Files:
        cmd-attach-session.c cmd-choose-session.c cmd-list-sessions.c 
        cmd-rename-session.c cmd-server-info.c cmd.c resize.c 
        server-fn.c server-window.c server.c session.c tmux.h 
Log Message:
Sync OpenBSD patchset 806:

Store sessions in an RB tree by name rather than a list, this is tidier
and allows them to easily be shown sorted in various lists
(list-sessions/choose-sessions).

Keep a session index which is used in a couple of places internally but
make it an ever-increasing number rather than filling in gaps with new
sessions.


Index: cmd.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd.c,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -d -r1.145 -r1.146
--- cmd.c       6 Dec 2010 21:48:56 -0000       1.145
+++ cmd.c       22 Dec 2010 15:36:44 -0000      1.146
@@ -111,7 +111,8 @@
        NULL
 };
 
-struct session *cmd_choose_session(struct sessions *);
+struct session *cmd_choose_session_list(struct sessionslist *);
+struct session *cmd_choose_session(void);
 struct client  *cmd_choose_client(struct clients *);
 struct client  *cmd_lookup_client(const char *);
 struct session *cmd_lookup_session(const char *, int *);
@@ -315,10 +316,9 @@
        struct msg_command_data *data = ctx->msgdata;
        struct client           *c = ctx->cmdclient;
        struct session          *s;
-       struct sessions          ss;
+       struct sessionslist      ss;
        struct winlink          *wl;
        struct window_pane      *wp;
-       u_int                    i;
        int                      found;
 
        if (ctx->curclient != NULL && ctx->curclient->session != NULL)
@@ -331,9 +331,7 @@
         */
        if (c != NULL && c->tty.path != NULL) {
                ARRAY_INIT(&ss);
-               for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-                       if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
-                               continue;
+               RB_FOREACH(s, sessions, &sessions) {
                        found = 0;
                        RB_FOREACH(wl, winlinks, &s->windows) {
                                TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@@ -349,25 +347,43 @@
                                ARRAY_ADD(&ss, s);
                }
 
-               s = cmd_choose_session(&ss);
+               s = cmd_choose_session_list(&ss);
                ARRAY_FREE(&ss);
                if (s != NULL)
                        return (s);
        }
 
        /* Use the session from the TMUX environment variable. */
-       if (data != NULL &&
-           data->pid == getpid() &&
-           data->idx <= ARRAY_LENGTH(&sessions) &&
-           (s = ARRAY_ITEM(&sessions, data->idx)) != NULL)
-               return (s);
+       if (data != NULL && data->pid == getpid()) {
+               s = session_find_by_index(data->idx);
+               if (s != NULL)
+                       return (s);
+       }
 
-       return (cmd_choose_session(&sessions));
+       return (cmd_choose_session());
+}
+
+/* Find the most recently used session. */
+struct session *
+cmd_choose_session(void)
+{
+       struct session  *s, *sbest;
+       struct timeval  *tv = NULL;
+
+       sbest = NULL;
+       RB_FOREACH(s, sessions, &sessions) {
+               if (tv == NULL || timercmp(&s->activity_time, tv, >)) {
+                       sbest = s;
+                       tv = &s->activity_time;
+               }
+       }
+
+       return (sbest);
 }
 
 /* Find the most recently used session from a list. */
 struct session *
-cmd_choose_session(struct sessions *ss)
+cmd_choose_session_list(struct sessionslist *ss)
 {
        struct session  *s, *sbest;
        struct timeval  *tv = NULL;
@@ -515,7 +531,6 @@
 cmd_lookup_session(const char *name, int *ambiguous)
 {
        struct session  *s, *sfound;
-       u_int            i;
 
        *ambiguous = 0;
 
@@ -524,21 +539,15 @@
         * be unique so an exact match can't be ambigious and can just be
         * returned.
         */
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
-                       continue;
-               if (strcmp(name, s->name) == 0)
-                       return (s);
-       }
+       if ((s = session_find(name)) != NULL)
+               return (s);
 
        /*
         * Otherwise look for partial matches, returning early if it is found to
         * be ambiguous.
         */
        sfound = NULL;
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
-                       continue;
+       RB_FOREACH(s, sessions, &sessions) {
                if (strncmp(name, s->name, strlen(name)) == 0 ||
                    fnmatch(name, s->name, 0) == 0) {
                        if (sfound != NULL) {

Index: cmd-choose-session.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-choose-session.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cmd-choose-session.c        22 Dec 2010 15:25:07 -0000      1.16
+++ cmd-choose-session.c        22 Dec 2010 15:36:44 -0000      1.17
@@ -55,7 +55,7 @@
        struct winlink                  *wl;
        struct session                  *s;
        struct session_group            *sg;
-       u_int                            i, idx, sgidx, cur;
+       u_int                            idx, sgidx, cur;
        char                             tmp[64];
 
        if (ctx->curclient == NULL) {
@@ -70,10 +70,7 @@
                return (0);
 
        cur = idx = 0;
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL)
-                       continue;
+       RB_FOREACH(s, sessions, &sessions) {
                if (s == ctx->curclient->session)
                        cur = idx;
                idx++;
@@ -86,7 +83,7 @@
                        xsnprintf(tmp, sizeof tmp, " (group %u)", sgidx);
                }
 
-               window_choose_add(wl->window->active, i,
+               window_choose_add(wl->window->active, s->idx,
                    "%s: %u windows [%ux%u]%s%s", s->name,
                    winlink_count(&s->windows), s->sx, s->sy,
                    tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
@@ -120,9 +117,7 @@
        if (cdata->client->flags & CLIENT_DEAD)
                return;
 
-       if ((u_int) idx > ARRAY_LENGTH(&sessions) - 1)
-               return;
-       s = ARRAY_ITEM(&sessions, idx);
+       s = session_find_by_index(idx);
        if (s == NULL)
                return;
        template = cmd_template_replace(cdata->template, s->name, 1);

Index: cmd-list-sessions.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-list-sessions.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- cmd-list-sessions.c 28 Nov 2009 14:50:36 -0000      1.25
+++ cmd-list-sessions.c 22 Dec 2010 15:36:44 -0000      1.26
@@ -46,14 +46,10 @@
        struct session          *s;
        struct session_group    *sg;
        char                    *tim, tmp[64];
-       u_int                    i, idx;
+       u_int                    idx;
        time_t                   t;
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL)
-                       continue;
-
+       RB_FOREACH(s, sessions, &sessions) {
                sg = session_group_find(s);
                if (sg == NULL)
                        *tmp = '\0';

Index: server-window.c
===================================================================
RCS file: /cvsroot/tmux/tmux/server-window.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- server-window.c     6 Dec 2010 22:52:21 -0000       1.18
+++ server-window.c     22 Dec 2010 15:36:44 -0000      1.19
@@ -38,17 +38,14 @@
        struct winlink          *wl;
        struct window_pane      *wp;
        struct session          *s;
-       u_int                    i, j;
+       u_int                    i;
 
        for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
                w = ARRAY_ITEM(&windows, i);
                if (w == NULL)
                        continue;
 
-               for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
-                       s = ARRAY_ITEM(&sessions, j);
-                       if (s == NULL)
-                               continue;
+               RB_FOREACH(s, sessions, &sessions) {
                        wl = session_has(s, w);
                        if (wl == NULL)
                                continue;

Index: server-fn.c
===================================================================
RCS file: /cvsroot/tmux/tmux/server-fn.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -d -r1.115 -r1.116
--- server-fn.c 22 Dec 2010 15:31:00 -0000      1.115
+++ server-fn.c 22 Dec 2010 15:36:44 -0000      1.116
@@ -30,13 +30,10 @@
 void
 server_fill_environ(struct session *s, struct environ *env)
 {
-       char             tmuxvar[MAXPATHLEN], *term;
-       u_int            idx;
+       char    tmuxvar[MAXPATHLEN], *term;
 
-       if (session_index(s, &idx) != 0)
-               fatalx("session not found");
        xsnprintf(tmuxvar, sizeof tmuxvar,
-           "%s,%ld,%u", socket_path, (long) getpid(), idx);
+           "%s,%ld,%u", socket_path, (long) getpid(), s->idx);
        environ_set(env, "TMUX", tmuxvar);
 
        term = options_get_string(&s->options, "default-terminal");
@@ -175,7 +172,6 @@
 server_status_window(struct window *w)
 {
        struct session  *s;
-       u_int            i;
 
        /*
         * This is slightly different. We want to redraw the status line of any
@@ -183,9 +179,8 @@
         * current window.
         */
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s != NULL && session_has(s, w) != NULL)
+       RB_FOREACH(s, sessions, &sessions) {
+               if (session_has(s, w) != NULL)
                        server_status_session(s);
        }
 }
@@ -246,11 +241,9 @@
 {
        struct session  *s;
        struct winlink  *wl;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL || session_has(s, w) == NULL)
+       RB_FOREACH(s, sessions, &sessions) {
+               if (session_has(s, w) == NULL)
                        continue;
                while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) {
                        if (session_detach(s, wl)) {
@@ -365,12 +358,10 @@
 server_next_session(struct session *s)
 {
        struct session *s_loop, *s_out;
-       u_int           i;
 
        s_out = NULL;
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s_loop = ARRAY_ITEM(&sessions, i);
-               if (s_loop == NULL || s_loop == s)
+       RB_FOREACH(s_loop, sessions, &sessions) {
+               if (s_loop == s)
                        continue;
                if (s_out == NULL ||
                    timercmp(&s_loop->activity_time, &s_out->activity_time, <))
@@ -411,15 +402,13 @@
 server_check_unattached (void)
 {
        struct session  *s;
-       u_int            i;
 
        /*
         * If any sessions are no longer attached and have destroy-unattached
         * set, collect them.
         */
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL || !(s->flags & SESSION_UNATTACHED))
+       RB_FOREACH(s, sessions, &sessions) {
+               if (!(s->flags & SESSION_UNATTACHED))
                        continue;
                if (options_get_number (&s->options, "destroy-unattached"))
                        session_destroy(s);

Index: cmd-server-info.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-server-info.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- cmd-server-info.c   10 Dec 2009 16:59:02 -0000      1.37
+++ cmd-server-info.c   22 Dec 2010 15:36:44 -0000      1.38
@@ -81,8 +81,6 @@
        else
                ctx->print(ctx, "configuration file not specified");
        ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
-       ctx->print(ctx, "%u clients, %u sessions",
-           ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
        ctx->print(ctx, "%s", "");
 
        ctx->print(ctx, "Clients:");
@@ -101,19 +99,14 @@
 
        ctx->print(ctx, "Sessions: [%zu/%zu]",
            sizeof (struct grid_cell), sizeof (struct grid_utf8));
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL)
-                       continue;
-
+       RB_FOREACH(s, sessions, &sessions) {
                t = s->creation_time.tv_sec;
                tim = ctime(&t);
                *strchr(tim, '\n') = '\0';
 
                ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
-                   "[flags=0x%x, references=%u]", i, s->name,
-                   winlink_count(&s->windows), tim, s->sx, s->sy, s->flags,
-                   s->references);
+                   "[flags=0x%x]", s->idx, s->name,
+                   winlink_count(&s->windows), tim, s->sx, s->sy, s->flags);
                RB_FOREACH(wl, winlinks, &s->windows) {
                        w = wl->window;
                        ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "

Index: cmd-attach-session.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-attach-session.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- cmd-attach-session.c        8 Feb 2010 18:27:34 -0000       1.36
+++ cmd-attach-session.c        22 Dec 2010 15:36:44 -0000      1.37
@@ -47,7 +47,7 @@
        char                    *overrides, *cause;
        u_int                    i;
 
-       if (ARRAY_LENGTH(&sessions) == 0) {
+       if (RB_EMPTY(&sessions)) {
                ctx->error(ctx, "no sessions");
                return (-1);
        }

Index: server.c
===================================================================
RCS file: /cvsroot/tmux/tmux/server.c,v
retrieving revision 1.248
retrieving revision 1.249
diff -u -d -r1.248 -r1.249
--- server.c    24 Oct 2010 19:54:41 -0000      1.248
+++ server.c    22 Dec 2010 15:36:44 -0000      1.249
@@ -146,8 +146,8 @@
        ARRAY_INIT(&windows);
        ARRAY_INIT(&clients);
        ARRAY_INIT(&dead_clients);
-       ARRAY_INIT(&sessions);
-       ARRAY_INIT(&dead_sessions);
+       RB_INIT(&sessions);
+       RB_INIT(&dead_sessions);
        TAILQ_INIT(&session_groups);
        mode_key_init_trees();
        key_bindings_init();
@@ -175,8 +175,8 @@
         * If there is a session already, put the current window and pane into
         * more mode.
         */
-       if (!ARRAY_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
-               wp = ARRAY_FIRST(&sessions)->curw->window->active;
+       if (!RB_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
+               wp = RB_MIN(sessions, &sessions)->curw->window->active;
                window_pane_set_mode(wp, &window_copy_mode);
                window_copy_init_for_output(wp);
                for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
@@ -224,10 +224,8 @@
        u_int   i;
 
        if (!options_get_number(&global_options, "exit-unattached")) {
-               for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-                       if (ARRAY_ITEM(&sessions, i) != NULL)
-                               return (0);
-               }
+               if (!RB_EMPTY(&sessions))
+                       return (0);
        }
        for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
                if (ARRAY_ITEM(&clients, i) != NULL)
@@ -241,7 +239,7 @@
 server_send_shutdown(void)
 {
        struct client   *c;
-       struct session  *s;
+       struct session  *s, *next_s;
        u_int            i;
 
        for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -255,9 +253,11 @@
                }
        }
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if ((s = ARRAY_ITEM(&sessions, i)) != NULL)
-                       session_destroy(s);
+       s = RB_MIN(sessions, &sessions);
+       while (s != NULL) {
+               next_s = RB_NEXT(sessions, &sessions, s);
+               session_destroy(s);
+               s = next_s;
        }
 }
 
@@ -265,16 +265,19 @@
 void
 server_clean_dead(void)
 {
-       struct session  *s;
+       struct session  *s, *next_s;
        struct client   *c;
        u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&dead_sessions); i++) {
-               s = ARRAY_ITEM(&dead_sessions, i);
-               if (s == NULL || s->references != 0)
-                       continue;
-               ARRAY_SET(&dead_sessions, i, NULL);
-               xfree(s);
+       s = RB_MIN(sessions, &dead_sessions);
+       while (s != NULL) {
+               next_s = RB_NEXT(sessions, &dead_sessions, s);
+               if (s->references == 0) {
+                       RB_REMOVE(sessions, &dead_sessions, s);
+                       xfree(s->name);
+                       xfree(s);
+               }
+               s = next_s;
        }
 
        for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
@@ -291,15 +294,13 @@
 server_update_socket(void)
 {
        struct session  *s;
-       u_int            i;
        static int       last = -1;
        int              n, mode;
        struct stat      sb;
 
        n = 0;
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
+       RB_FOREACH(s, sessions, &sessions) {
+               if (!(s->flags & SESSION_UNATTACHED)) {
                        n++;
                        break;
                }
@@ -486,15 +487,11 @@
 server_lock_server(void)
 {
        struct session  *s;
-       u_int            i;
        int              timeout;
        time_t           t;
 
        t = time(NULL);
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
-                       continue;
-
+       RB_FOREACH(s, sessions, &sessions) {
                if (s->flags & SESSION_UNATTACHED) {
                        if (gettimeofday(&s->activity_time, NULL) != 0)
                                fatal("gettimeofday failed");
@@ -515,15 +512,11 @@
 server_lock_sessions(void)
 {
        struct session  *s;
-       u_int            i;
        int              timeout;
        time_t           t;
 
        t = time(NULL);
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
-                       continue;
-
+       RB_FOREACH(s, sessions, &sessions) {
                if (s->flags & SESSION_UNATTACHED) {
                        if (gettimeofday(&s->activity_time, NULL) != 0)
                                fatal("gettimeofday failed");

Index: cmd-rename-session.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-rename-session.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cmd-rename-session.c        11 Aug 2010 22:19:03 -0000      1.20
+++ cmd-rename-session.c        22 Dec 2010 15:36:44 -0000      1.21
@@ -53,8 +53,10 @@
        if ((s = cmd_find_session(ctx, data->target)) == NULL)
                return (-1);
 
+       RB_REMOVE(sessions, &sessions, s);
        xfree(s->name);
        s->name = xstrdup(data->arg);
+       RB_INSERT(sessions, &sessions, s);
 
        server_status_session(s);
 

Index: resize.c
===================================================================
RCS file: /cvsroot/tmux/tmux/resize.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- resize.c    6 Dec 2010 21:57:56 -0000       1.26
+++ resize.c    22 Dec 2010 15:36:44 -0000      1.27
@@ -52,11 +52,7 @@
        u_int                    i, j, ssx, ssy, has, limit;
        int                      flag;
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s == NULL)
-                       continue;
-
+       RB_FOREACH(s, sessions, &sessions) {
                ssx = ssy = UINT_MAX;
                for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
                        c = ARRAY_ITEM(&clients, j);
@@ -98,9 +94,8 @@
                flag = options_get_number(&w->options, "aggressive-resize");
 
                ssx = ssy = UINT_MAX;
-               for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
-                       s = ARRAY_ITEM(&sessions, j);
-                       if (s == NULL || s->flags & SESSION_UNATTACHED)
+               RB_FOREACH(s, sessions, &sessions) {
+                       if (s->flags & SESSION_UNATTACHED)
                                continue;
                        if (flag)
                                has = s->curw->window == w;

Index: session.c
===================================================================
RCS file: /cvsroot/tmux/tmux/session.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- session.c   22 Dec 2010 15:33:14 -0000      1.82
+++ session.c   22 Dec 2010 15:36:44 -0000      1.83
@@ -29,11 +29,20 @@
 /* Global session list. */
 struct sessions        sessions;
 struct sessions dead_sessions;
+u_int          next_session;
 struct session_groups session_groups;
 
 struct winlink *session_next_alert(struct winlink *);
 struct winlink *session_previous_alert(struct winlink *);
 
+RB_GENERATE(sessions, session, entry, session_cmp);
+
+int
+session_cmp(struct session *s1, struct session *s2)
+{
+       return (strcmp(s1->name, s2->name));
+}
+
 /*
  * Find if session is still alive. This is true if it is still on the global
  * sessions list.
@@ -41,24 +50,35 @@
 int
 session_alive(struct session *s)
 {
-       u_int   idx;
+       struct session *s_loop;
 
-       return (session_index(s, &idx) == 0);
+       RB_FOREACH(s_loop, sessions, &sessions) {
+               if (s_loop == s)
+                       return (1);
+       }
+       return (0);
 }
 
 /* Find session by name. */
 struct session *
 session_find(const char *name)
 {
+       struct session  s;
+
+       s.name = (char *) name;
+       return (RB_FIND(sessions, &sessions, &s));
+}
+
+/* Find session by index. */
+struct session *
+session_find_by_index(u_int idx)
+{
        struct session  *s;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               s = ARRAY_ITEM(&sessions, i);
-               if (s != NULL && strcmp(s->name, name) == 0)
+       RB_FOREACH(s, sessions, &sessions) {
+               if (s->idx == idx)
                        return (s);
        }
-
        return (NULL);
 }
 
@@ -69,7 +89,6 @@
     char **cause)
 {
        struct session  *s;
-       u_int            i;
 
        s = xmalloc(sizeof *s);
        s->references = 0;
@@ -101,19 +120,12 @@
        s->sx = sx;
        s->sy = sy;
 
-       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
-               if (ARRAY_ITEM(&sessions, i) == NULL) {
-                       ARRAY_SET(&sessions, i, s);
-                       break;
-               }
-       }
-       if (i == ARRAY_LENGTH(&sessions))
-               ARRAY_ADD(&sessions, s);
-
+       s->idx = next_session++;
        if (name != NULL)
                s->name = xstrdup(name);
        else
-               xasprintf(&s->name, "%u", i);
+               xasprintf(&s->name, "%u", s->idx);
+       RB_INSERT(sessions, &sessions, s);
 
        if (cmd != NULL) {
                if (session_new(s, NULL, cmd, cwd, idx, cause) == NULL) {
@@ -132,15 +144,9 @@
 void
 session_destroy(struct session *s)
 {
-       u_int   i;
-
        log_debug("session %s destroyed", s->name);
 
-       if (session_index(s, &i) != 0)
-               fatalx("session not found");
-       ARRAY_SET(&sessions, i, NULL);
-       while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
-               ARRAY_TRUNC(&sessions, 1);
+       RB_REMOVE(sessions, &sessions, s);
 
        if (s->tio != NULL)
                xfree(s->tio);
@@ -156,27 +162,8 @@
                winlink_remove(&s->windows, RB_ROOT(&s->windows));
 
        xfree(s->cwd);
-       xfree(s->name);
-
-       for (i = 0; i < ARRAY_LENGTH(&dead_sessions); i++) {
-               if (ARRAY_ITEM(&dead_sessions, i) == NULL) {
-                       ARRAY_SET(&dead_sessions, i, s);
-                       break;
-               }
-       }
-       if (i == ARRAY_LENGTH(&dead_sessions))
-               ARRAY_ADD(&dead_sessions, s);
-}
 
-/* Find session index. */
-int
-session_index(struct session *s, u_int *i)
-{
-       for (*i = 0; *i < ARRAY_LENGTH(&sessions); (*i)++) {
-               if (s == ARRAY_ITEM(&sessions, *i))
-                       return (0);
-       }
-       return (-1);
+       RB_INSERT(sessions, &dead_sessions, s);
 }
 
 /* Find the next usable session. */
@@ -184,19 +171,18 @@
 session_next_session(struct session *s)
 {
        struct session *s2;
-       u_int           i;
 
-       if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
+       if (RB_EMPTY(&sessions) || !session_alive(s))
                return (NULL);
 
+       s2 = s;
        do {
-               if (i == ARRAY_LENGTH(&sessions) - 1)
-                       i = 0;
-               else
-                       i++;
-               s2 = ARRAY_ITEM(&sessions, i);
-       } while (s2 == NULL);
-
+               s2 = RB_NEXT(sessions, &sessions, s2);
+               if (s2 == NULL)
+                       s2 = RB_MIN(sessions, &sessions);
+       } while (s2 != s);
+       if (s2 == s)
+               return (NULL);
        return (s2);
 }
 
@@ -205,19 +191,18 @@
 session_previous_session(struct session *s)
 {
        struct session *s2;
-       u_int           i;
 
-       if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
+       if (RB_EMPTY(&sessions) || !session_alive(s))
                return (NULL);
 
+       s2 = s;
        do {
-               if (i == 0)
-                       i = ARRAY_LENGTH(&sessions) - 1;
-               else
-                       i--;
-               s2 = ARRAY_ITEM(&sessions, i);
-       } while (s2 == NULL);
-
+               s2 = RB_PREV(sessions, &sessions, s2);
+               if (s2 == NULL)
+                       s2 = RB_MAX(sessions, &sessions);
+       } while (s2 != s);
+       if (s2 == s)
+               return (NULL);
        return (s2);
 }
 

Index: tmux.h
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.h,v
retrieving revision 1.590
retrieving revision 1.591
diff -u -d -r1.590 -r1.591
--- tmux.h      22 Dec 2010 15:31:56 -0000      1.590
+++ tmux.h      22 Dec 2010 15:36:44 -0000      1.591
@@ -928,6 +928,8 @@
 TAILQ_HEAD(session_groups, session_group);
 
 struct session {
+       u_int            idx;
+
        char            *name;
        char            *cwd;
 
@@ -955,8 +957,10 @@
        int              references;
 
        TAILQ_ENTRY(session) gentry;
+       RB_ENTRY(session)    entry;
 };
-ARRAY_DECL(sessions, struct session *);
+RB_HEAD(sessions, session);
+ARRAY_DECL(sessionslist, struct session *);
 
 /* TTY information. */
 struct tty_key {
@@ -1965,13 +1969,15 @@
 extern struct sessions sessions;
 extern struct sessions dead_sessions;
 extern struct session_groups session_groups;
+int    session_cmp(struct session *, struct session *);
+RB_PROTOTYPE(sessions, session, entry, session_cmp);
 int             session_alive(struct session *);
 struct session *session_find(const char *);
+struct session *session_find_by_index(u_int);
 struct session *session_create(const char *, const char *, const char *,
                     struct environ *, struct termios *, int, u_int, u_int,
                     char **);
 void            session_destroy(struct session *);
-int             session_index(struct session *, u_int *);
 struct session *session_next_session(struct session *);
 struct session *session_previous_session(struct session *);
 struct winlink *session_new(struct session *,


------------------------------------------------------------------------------
Forrester recently released a report on the Return on Investment (ROI) of
Google Apps. They found a 300% ROI, 38%-56% cost savings, and break-even
within 7 months.  Over 3 million businesses have gone Google with Google Apps:
an online email calendar, and document program that's accessible from your 
browser. Read the Forrester report: http://p.sf.net/sfu/googleapps-sfnew
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to