diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2014-08-02 17:01:05 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-08-02 21:33:55 +0200 |
commit | facd8105481b2af1f8c519905c8150e6da5347ea (patch) | |
tree | cb1290afbea94c59706214ddb43b2f5be1d3022f | |
parent | e8ddf5e58c9e72647abe102713a9190c638cb07b (diff) | |
download | xK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.gz xK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.xz xK-facd8105481b2af1f8c519905c8150e6da5347ea.zip |
kike: implement clean shutdown
-rw-r--r-- | src/kike.c | 33 |
1 files changed, 25 insertions, 8 deletions
@@ -423,7 +423,6 @@ server_context_free (struct server_context *self) if (self->ssl_ctx) SSL_CTX_free (self->ssl_ctx); - // TODO: terminate the connections properly before this is called struct client *link, *tmp; for (link = self->clients; link; link = tmp) { @@ -465,6 +464,13 @@ client_unregister (struct client *c, const char *reason) } static void +irc_try_finish_quit (struct server_context *ctx) +{ + if (!ctx->n_clients && ctx->quitting) + ctx->polling = false; +} + +static void client_kill (struct client *c, const char *reason) { client_unregister (c, reason ? reason : "Client exited"); @@ -483,6 +489,8 @@ client_kill (struct client *c, const char *reason) LIST_UNLINK (ctx->clients, c); ctx->n_clients--; free (c); + + irc_try_finish_quit (ctx); } static void @@ -1266,8 +1274,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data) exit_fatal ("%s: %s", "accept", strerror (errno)); } - if (ctx->max_connections != 0 - && ctx->n_clients >= ctx->max_connections) + if (ctx->max_connections != 0 && ctx->n_clients >= ctx->max_connections) { print_debug ("connection limit reached, refusing connection"); close (fd); @@ -1580,13 +1587,23 @@ on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx) char *dummy; (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 0 - initiate_quit (ctx); -#endif + print_status ("shutting down"); + + 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); } } |