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 /src/kike.c | |
| parent | e8ddf5e58c9e72647abe102713a9190c638cb07b (diff) | |
| download | xK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.gz xK-facd8105481b2af1f8c519905c8150e6da5347ea.tar.xz xK-facd8105481b2af1f8c519905c8150e6da5347ea.zip | |
kike: implement clean shutdown
Diffstat (limited to 'src/kike.c')
| -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);  	}  } | 
