version 1.121, 2015/04/22 15:30:11 |
version 1.122, 2015/04/24 23:17:11 |
|
|
|
|
RB_INIT(&windows); |
RB_INIT(&windows); |
RB_INIT(&all_window_panes); |
RB_INIT(&all_window_panes); |
ARRAY_INIT(&clients); |
TAILQ_INIT(&clients); |
ARRAY_INIT(&dead_clients); |
TAILQ_INIT(&dead_clients); |
RB_INIT(&sessions); |
RB_INIT(&sessions); |
RB_INIT(&dead_sessions); |
RB_INIT(&dead_sessions); |
TAILQ_INIT(&session_groups); |
TAILQ_INIT(&session_groups); |
|
|
cfg_cmd_q->emptyfn = cfg_default_done; |
cfg_cmd_q->emptyfn = cfg_default_done; |
cfg_finished = 0; |
cfg_finished = 0; |
cfg_references = 1; |
cfg_references = 1; |
cfg_client = ARRAY_FIRST(&clients); |
cfg_client = TAILQ_FIRST(&clients); |
if (cfg_client != NULL) |
if (cfg_client != NULL) |
cfg_client->references++; |
cfg_client->references++; |
|
|
|
|
server_should_shutdown(void) |
server_should_shutdown(void) |
{ |
{ |
struct client *c; |
struct client *c; |
u_int i; |
|
|
|
if (!options_get_number(&global_options, "exit-unattached")) { |
if (!options_get_number(&global_options, "exit-unattached")) { |
if (!RB_EMPTY(&sessions)) |
if (!RB_EMPTY(&sessions)) |
return (0); |
return (0); |
} |
} |
|
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
TAILQ_FOREACH(c, &clients, entry) { |
c = ARRAY_ITEM(&clients, i); |
if (c->session != NULL) |
if (c != NULL && c->session != NULL) |
|
return (0); |
return (0); |
} |
} |
|
|
|
|
* clients but don't actually exit until they've gone. |
* clients but don't actually exit until they've gone. |
*/ |
*/ |
cmd_wait_for_flush(); |
cmd_wait_for_flush(); |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
if (!TAILQ_EMPTY(&clients)) |
if (ARRAY_ITEM(&clients, i) != NULL) |
return (0); |
return (0); |
|
} |
|
|
|
return (1); |
return (1); |
} |
} |
|
|
void |
void |
server_send_shutdown(void) |
server_send_shutdown(void) |
{ |
{ |
struct client *c; |
struct client *c, *c1; |
struct session *s, *next_s; |
struct session *s, *s1; |
u_int i; |
|
|
|
cmd_wait_for_flush(); |
cmd_wait_for_flush(); |
|
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
TAILQ_FOREACH_SAFE(c, &clients, entry, c1) { |
c = ARRAY_ITEM(&clients, i); |
if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED)) |
if (c != NULL) { |
server_client_lost(c); |
if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED)) |
else |
server_client_lost(c); |
server_write_client(c, MSG_SHUTDOWN, NULL, 0); |
else |
c->session = NULL; |
server_write_client(c, MSG_SHUTDOWN, NULL, 0); |
|
c->session = NULL; |
|
} |
|
} |
} |
|
|
s = RB_MIN(sessions, &sessions); |
RB_FOREACH_SAFE(s, sessions, &sessions, s1) |
while (s != NULL) { |
|
next_s = RB_NEXT(sessions, &sessions, s); |
|
session_destroy(s); |
session_destroy(s); |
s = next_s; |
|
} |
|
} |
} |
|
|
/* Free dead, unreferenced clients and sessions. */ |
/* Free dead, unreferenced clients and sessions. */ |
void |
void |
server_clean_dead(void) |
server_clean_dead(void) |
{ |
{ |
struct session *s, *next_s; |
struct session *s, *s1; |
struct client *c; |
struct client *c, *c1; |
u_int i; |
|
|
|
s = RB_MIN(sessions, &dead_sessions); |
RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) { |
while (s != NULL) { |
if (s->references != 0) |
next_s = RB_NEXT(sessions, &dead_sessions, s); |
continue; |
if (s->references == 0) { |
RB_REMOVE(sessions, &dead_sessions, s); |
RB_REMOVE(sessions, &dead_sessions, s); |
free(s->name); |
free(s->name); |
free(s); |
free(s); |
|
} |
|
s = next_s; |
|
} |
} |
|
|
for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) { |
TAILQ_FOREACH_SAFE(c, &dead_clients, entry, c1) { |
c = ARRAY_ITEM(&dead_clients, i); |
if (c->references != 0) |
if (c == NULL || c->references != 0) |
|
continue; |
continue; |
ARRAY_SET(&dead_clients, i, NULL); |
TAILQ_REMOVE(&dead_clients, c, entry); |
free(c); |
free(c); |
} |
} |
} |
} |