kike: implement clean shutdown

This commit is contained in:
Přemysl Eric Janouch 2014-08-02 17:01:05 +02:00
parent e8ddf5e58c
commit facd810548
1 changed files with 25 additions and 8 deletions

View File

@ -423,7 +423,6 @@ server_context_free (struct server_context *self)
if (self->ssl_ctx) if (self->ssl_ctx)
SSL_CTX_free (self->ssl_ctx); SSL_CTX_free (self->ssl_ctx);
// TODO: terminate the connections properly before this is called
struct client *link, *tmp; struct client *link, *tmp;
for (link = self->clients; link; link = tmp) for (link = self->clients; link; link = tmp)
{ {
@ -464,6 +463,13 @@ client_unregister (struct client *c, const char *reason)
c->registered = false; c->registered = false;
} }
static void
irc_try_finish_quit (struct server_context *ctx)
{
if (!ctx->n_clients && ctx->quitting)
ctx->polling = false;
}
static void static void
client_kill (struct client *c, const char *reason) client_kill (struct client *c, const char *reason)
{ {
@ -483,6 +489,8 @@ client_kill (struct client *c, const char *reason)
LIST_UNLINK (ctx->clients, c); LIST_UNLINK (ctx->clients, c);
ctx->n_clients--; ctx->n_clients--;
free (c); free (c);
irc_try_finish_quit (ctx);
} }
static void static void
@ -1266,8 +1274,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data)
exit_fatal ("%s: %s", "accept", strerror (errno)); exit_fatal ("%s: %s", "accept", strerror (errno));
} }
if (ctx->max_connections != 0 if (ctx->max_connections != 0 && ctx->n_clients >= ctx->max_connections)
&& ctx->n_clients >= ctx->max_connections)
{ {
print_debug ("connection limit reached, refusing connection"); print_debug ("connection limit reached, refusing connection");
close (fd); close (fd);
@ -1580,13 +1587,23 @@ on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx)
char *dummy; char *dummy;
(void) read (fd->fd, &dummy, 1); (void) read (fd->fd, &dummy, 1);
// TODO: send ERROR messages to anyone, wait for the messages to get
// dispatched for a few seconds, RST the rest and quit.
if (g_termination_requested && !ctx->quitting) if (g_termination_requested && !ctx->quitting)
{ {
#if 0 print_status ("shutting down");
initiate_quit (ctx);
#endif for (struct client *iter = ctx->clients; iter; iter = iter->next)
if (!iter->closing_link)
irc_close_link (iter, "Shutting down");
ssize_t i = poller_find_by_fd (&ctx->poller, ctx->listen_fd);
if (soft_assert (i != -1))
poller_remove_at_index (&ctx->poller, i);
if (ctx->listen_fd != -1)
xclose (ctx->listen_fd);
ctx->listen_fd = -1;
ctx->quitting = true;
irc_try_finish_quit (ctx);
} }
} }