aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2014-08-02 17:01:05 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2014-08-02 21:33:55 +0200
commitfacd8105481b2af1f8c519905c8150e6da5347ea (patch)
treecb1290afbea94c59706214ddb43b2f5be1d3022f /src
parente8ddf5e58c9e72647abe102713a9190c638cb07b (diff)
downloadxK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.gz
xK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.xz
xK-facd8105481b2af1f8c519905c8150e6da5347ea.zip
kike: implement clean shutdown
Diffstat (limited to 'src')
-rw-r--r--src/kike.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/kike.c b/src/kike.c
index 9a744c2..d9b8291 100644
--- a/src/kike.c
+++ b/src/kike.c
@@ -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);
}
}