diff options
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 113 |
1 files changed, 49 insertions, 64 deletions
@@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.82 2010-12-22 15:33:14 tcunha Exp $ */ +/* $Id: session.c,v 1.83 2010-12-22 15:36:44 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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 @@ struct winlink *session_previous_alert(struct winlink *); 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 @@ session_create(const char *name, const char *cmd, const char *cwd, char **cause) { struct session *s; - u_int i; s = xmalloc(sizeof *s); s->references = 0; @@ -101,19 +120,12 @@ session_create(const char *name, const char *cmd, const char *cwd, 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 @@ session_create(const char *name, const char *cmd, const char *cwd, 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 @@ session_destroy(struct session *s) 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 @@ struct session * 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 @@ struct session * 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); } |