Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client disconnect on SIGINT #49

Merged
merged 5 commits into from
Mar 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions examples/audit-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <limits.h>
#include <string.h>
#include <assert.h>
#include <locale.h>

#include "discord.h"

Expand Down Expand Up @@ -124,8 +123,6 @@ main(int argc, char *argv[])
else
config_file = "../config.json";

setlocale(LC_ALL, "");

ccord_global_init();
struct discord *client = discord_config_init(config_file);
assert(NULL != client && "Couldn't initialize client");
Expand Down
12 changes: 12 additions & 0 deletions include/concord-once.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@

#ifndef CONCORD_ONCE_H

/**
* @brief If `SIGINT` is detected client(s) will be disconnected from their
* on-going session
*
* This global shall be set if a `SIGINT` is detected, running clients will
* then attempt to perform a clean disconnect, rather then just letting
* the program end abruptly.
* @note client shall only attempt to disconnect if there aren't any active
* events waiting to be listened or reacted to
*/
extern int ccord_has_sigint;

/**
* @brief Initialize global shared-resources not API-specific
*
Expand Down
4 changes: 2 additions & 2 deletions include/discord-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ void discord_bucket_build(struct discord_adapter *adapter,
const char route[DISCORD_ROUTE_LEN],
struct ua_info *info);

/** @} DIscordInternalAdapterRatelimit */
/** @} DiscordInternalAdapterRatelimit */

/** @} DiscordInternalAdapter */

Expand Down Expand Up @@ -498,7 +498,7 @@ struct discord_gateway_cbs {
discord_ev_voice_server_update on_voice_server_update;
};

/** @defgroup DiscordInternalGatewaySessionStatus
/** @defgroup DiscordInternalGatewaySessionStatus Client's session status
* @brief Client's session status
* @{ */
/** client is currently offline */
Expand Down
37 changes: 27 additions & 10 deletions src/concord-once.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
#include <signal.h>
#include <curl/curl.h>

#include "error.h"
#include "work.h"

/* if set to 1 then client(s) will be disconnected */
int ccord_has_sigint = 0;

static int once;

/* shutdown gracefully on SIGINT received */
static void
sigint_handler(int signum)
{
(void)signum;
fputs("\nSIGINT: Disconnecting running concord client(s) ...\n", stderr);
ccord_has_sigint = 1;
}

CCORDcode
ccord_global_init()
{
if (once) return CCORD_GLOBAL_INIT;

if (0 != curl_global_init(CURL_GLOBAL_DEFAULT)) {
fprintf(stderr, "Couldn't start libcurl's globals\n");
if (once) {
return CCORD_GLOBAL_INIT;
}
if (work_global_init()) {
fprintf(stderr, "Attempt duplicate global initialization\n");
return CCORD_GLOBAL_INIT;
else {
__sighandler_t prev = signal(SIGINT, &sigint_handler);
if (prev != SIG_DFL && prev != sigint_handler)
signal(SIGINT, prev);
if (0 != curl_global_init(CURL_GLOBAL_DEFAULT)) {
fputs("Couldn't start libcurl's globals\n", stderr);
return CCORD_GLOBAL_INIT;
}
if (work_global_init()) {
fputs("Attempt duplicate global initialization\n", stderr);
return CCORD_GLOBAL_INIT;
}
once = 1;
}

once = 1;

return CCORD_OK;
}

Expand Down
8 changes: 5 additions & 3 deletions src/discord-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,9 @@ discord_run(struct discord *client)
if (-1 == poll_result) {
/* TODO: handle poll error here */
}
else if (0 == poll_result && client->on_idle) {
client->on_idle(client);
else if (0 == poll_result) {
if (ccord_has_sigint != 0) discord_shutdown(client);
if (client->on_idle) client->on_idle(client);
}

if (client->on_cycle) client->on_cycle(client);
Expand Down Expand Up @@ -387,7 +388,8 @@ discord_run(struct discord *client)
void
discord_shutdown(struct discord *client)
{
discord_gateway_shutdown(&client->gw);
if (client->gw.session->status != DISCORD_SESSION_SHUTDOWN)
discord_gateway_shutdown(&client->gw);
}

void
Expand Down
15 changes: 1 addition & 14 deletions test/async.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strcmp() */
#include <signal.h>
#include <pthread.h>
#include <assert.h>

#include "discord.h"

struct discord *client;

struct user_cxt {
u64snowflake channel_id;
unsigned long long counter;
Expand Down Expand Up @@ -170,15 +167,6 @@ on_force_error(struct discord *client, const struct discord_message *msg)
});
}

/* shutdown gracefully on SIGINT received */
void
sigint_handler(int signum)
{
(void)signum;
log_info("SIGINT received, shutting down ...");
discord_shutdown(client);
}

int
main(int argc, char *argv[])
{
Expand All @@ -188,10 +176,9 @@ main(int argc, char *argv[])
else
config_file = "../config.json";

signal(SIGINT, &sigint_handler);
ccord_global_init();

client = discord_config_init(config_file);
struct discord *client = discord_config_init(config_file);
assert(NULL != client && "Couldn't initialize client");

struct user_cxt cxt = { 0 };
Expand Down