-/* $OpenBSD: server-client.c,v 1.140 2015/06/04 23:27:51 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.141 2015/06/05 18:01:12 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#include "tmux.h"
void server_client_key_table(struct client *, const char *);
+void server_client_free(int, short, void *);
void server_client_check_focus(struct window_pane *);
void server_client_check_resize(struct window_pane *);
int server_client_check_mouse(struct client *);
setblocking(fd, 0);
c = xcalloc(1, sizeof *c);
- c->references = 0;
+ c->references = 1;
imsg_init(&c->ibuf, fd);
server_update_event(c);
{
struct message_entry *msg, *msg1;
+ c->flags |= CLIENT_DEAD;
+
+ status_prompt_clear(c);
+ status_message_clear(c);
+
+ if (c->stdin_callback != NULL)
+ c->stdin_callback(c, 1, c->stdin_callback_data);
+
TAILQ_REMOVE(&clients, c, entry);
log_debug("lost client %d", c->ibuf.fd);
if (event_initialized(&c->event))
event_del(&c->event);
- TAILQ_INSERT_TAIL(&dead_clients, c, entry);
- c->flags |= CLIENT_DEAD;
+ server_client_deref(c);
server_add_accept(0); /* may be more file descriptors now */
server_update_socket();
}
+/* Remove reference from a client. */
+void
+server_client_deref(struct client *c)
+{
+ log_debug("deref client %d (%d references)", c->ibuf.fd, c->references);
+
+ c->references--;
+ if (c->references == 0)
+ event_once(-1, EV_TIMEOUT, server_client_free, c, NULL);
+}
+
+/* Free dead client. */
+void
+server_client_free(unused int fd, unused short events, void *arg)
+{
+ struct client *c = arg;
+
+ log_debug("free client %d (%d references)", c->ibuf.fd, c->references);
+
+ if (c->references == 0)
+ free(c);
+}
+
/* Process a single client event. */
void
server_client_callback(int fd, short events, void *data)
-/* $OpenBSD: server.c,v 1.126 2015/06/04 11:43:51 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.127 2015/06/05 18:01:12 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Main server functions.
*/
-/* Client list. */
struct clients clients;
-struct clients dead_clients;
int server_fd;
int server_shutdown;
RB_INIT(&windows);
RB_INIT(&all_window_panes);
TAILQ_INIT(&clients);
- TAILQ_INIT(&dead_clients);
RB_INIT(&sessions);
RB_INIT(&dead_sessions);
TAILQ_INIT(&session_groups);
server_clean_dead(void)
{
struct session *s, *s1;
- struct client *c, *c1;
RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) {
if (s->references != 0)
free(s->name);
free(s);
}
-
- TAILQ_FOREACH_SAFE(c, &dead_clients, entry, c1) {
- if (c->references != 0)
- continue;
- TAILQ_REMOVE(&dead_clients, c, entry);
- free(c);
- }
}
/* Update socket execute permissions based on whether sessions are attached. */
-/* $OpenBSD: tmux.h,v 1.517 2015/06/04 23:27:51 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.518 2015/06/05 18:01:12 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
void server_client_handle_key(struct client *, int);
void server_client_create(int);
int server_client_open(struct client *, char **);
+void server_client_deref(struct client *);
void server_client_lost(struct client *);
void server_client_callback(int, short, void *);
void server_client_status_timer(void);