Similarly, for sessions use a callback to free rather than checking
authornicm <nicm@openbsd.org>
Fri, 5 Jun 2015 18:18:32 +0000 (18:18 +0000)
committernicm <nicm@openbsd.org>
Fri, 5 Jun 2015 18:18:32 +0000 (18:18 +0000)
every loop.

usr.bin/tmux/notify.c
usr.bin/tmux/server.c
usr.bin/tmux/session.c
usr.bin/tmux/tmux.h
usr.bin/tmux/window-choose.c

index 1662195..e9a8cfe 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: notify.c,v 1.7 2015/06/05 18:06:30 nicm Exp $ */
+/* $OpenBSD: notify.c,v 1.8 2015/06/05 18:18:32 nicm Exp $ */
 
 /*
  * Copyright (c) 2012 George Nachman <tmux@georgester.com>
@@ -123,7 +123,7 @@ notify_drain(void)
                if (ne->client != NULL)
                        server_client_unref(ne->client);
                if (ne->session != NULL)
-                       ne->session->references--;
+                       session_unref(ne->session);
                if (ne->window != NULL)
                        window_remove_ref(ne->window);
 
index 4f157fd..9e63221 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.127 2015/06/05 18:01:12 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.128 2015/06/05 18:18:32 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -58,7 +58,6 @@ int   server_create_socket(void);
 void   server_loop(void);
 int    server_should_shutdown(void);
 void   server_send_shutdown(void);
-void   server_clean_dead(void);
 void   server_accept_callback(int, short, void *);
 void   server_signal_callback(int, short, void *);
 void   server_child_signal(void);
@@ -204,7 +203,6 @@ server_start(int lockfd, char *lockfile)
        RB_INIT(&all_window_panes);
        TAILQ_INIT(&clients);
        RB_INIT(&sessions);
-       RB_INIT(&dead_sessions);
        TAILQ_INIT(&session_groups);
        mode_key_init_trees();
        key_bindings_init();
@@ -264,8 +262,6 @@ server_loop(void)
 
                server_window_loop();
                server_client_loop();
-
-               server_clean_dead();
        }
 }
 
@@ -317,21 +313,6 @@ server_send_shutdown(void)
                session_destroy(s);
 }
 
-/* Free dead, unreferenced clients and sessions. */
-void
-server_clean_dead(void)
-{
-       struct session  *s, *s1;
-
-       RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) {
-               if (s->references != 0)
-                       continue;
-               RB_REMOVE(sessions, &dead_sessions, s);
-               free(s->name);
-               free(s);
-       }
-}
-
 /* Update socket execute permissions based on whether sessions are attached. */
 void
 server_update_socket(void)
index 39d2d1a..e4a2305 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.49 2015/05/06 08:35:39 nicm Exp $ */
+/* $OpenBSD: session.c,v 1.50 2015/06/05 18:18:32 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 
 #include "tmux.h"
 
-/* Global session list. */
 struct sessions        sessions;
-struct sessions dead_sessions;
 u_int          next_session_id;
 struct session_groups session_groups;
 
+void   session_free(int, short, void *);
+
 struct winlink *session_next_alert(struct winlink *);
 struct winlink *session_previous_alert(struct winlink *);
 
@@ -109,7 +109,7 @@ session_create(const char *name, int argc, char **argv, const char *path,
        struct winlink  *wl;
 
        s = xmalloc(sizeof *s);
-       s->references = 0;
+       s->references = 1;
        s->flags = 0;
 
        if (gettimeofday(&s->creation_time, NULL) != 0)
@@ -164,6 +164,29 @@ session_create(const char *name, int argc, char **argv, const char *path,
        return (s);
 }
 
+/* Remove a reference from a session. */
+void
+session_unref(struct session *s)
+{
+       log_debug("session %s has %d references", s->name, s->references);
+
+       s->references--;
+       if (s->references == 0)
+               event_once(-1, EV_TIMEOUT, session_free, s, NULL);
+}
+
+/* Free session. */
+void
+session_free(unused int fd, unused short events, void *arg)
+{
+       struct session  *s = arg;
+
+       log_debug("sesson %s freed (%d references)", s->name, s->references);
+
+       if (s->references == 0)
+               free(s);
+}
+
 /* Destroy a session. */
 void
 session_destroy(struct session *s)
@@ -191,7 +214,7 @@ session_destroy(struct session *s)
 
        close(s->cwd);
 
-       RB_INSERT(sessions, &dead_sessions, s);
+       session_unref(s);
 }
 
 /* Check a session name is valid: not empty and no colons or periods. */
index 86879dc..be9c2f8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.519 2015/06/05 18:06:30 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.520 2015/06/05 18:18:32 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -2259,7 +2259,6 @@ void      control_notify_session_close(struct session *);
 
 /* session.c */
 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);
@@ -2271,6 +2270,7 @@ struct session    *session_create(const char *, int, char **, const char *,
                     int, struct environ *, struct termios *, int, u_int,
                     u_int, char **);
 void            session_destroy(struct session *);
+void            session_unref(struct session *);
 int             session_check_name(const char *);
 void            session_update_activity(struct session *);
 struct session *session_next_session(struct session *);
index 586f42b..38141c5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-choose.c,v 1.64 2015/05/08 16:23:34 nicm Exp $ */
+/* $OpenBSD: window-choose.c,v 1.65 2015/06/05 18:18:32 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -209,11 +209,11 @@ window_choose_data_create(int type, struct client *c, struct session *s)
 void
 window_choose_data_free(struct window_choose_data *wcd)
 {
-       wcd->start_client->references--;
-       wcd->start_session->references--;
+       server_client_unref(wcd->start_client);
+       session_unref(wcd->start_session);
 
        if (wcd->tree_session != NULL)
-               wcd->tree_session->references--;
+               session_unref(wcd->tree_session);
 
        free(wcd->ft_template);
        format_free(wcd->ft);