From d92f72acc71436d38644ee19f1c0ff559b985b60 Mon Sep 17 00:00:00 2001 From: lcsmuller Date: Fri, 18 Mar 2022 19:20:57 -0300 Subject: [PATCH 1/6] feat: clean disconnect on SIGINT received --- include/concord-once.h | 12 ++++++++++++ include/discord-internal.h | 4 ++-- src/concord-once.c | 14 ++++++++++++++ src/discord-client.c | 8 +++++--- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/include/concord-once.h b/include/concord-once.h index b1b76c501..3476d68ea 100644 --- a/include/concord-once.h +++ b/include/concord-once.h @@ -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 abruply. + * @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 * diff --git a/include/discord-internal.h b/include/discord-internal.h index 016b156e6..bf92d49db 100644 --- a/include/discord-internal.h +++ b/include/discord-internal.h @@ -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 */ @@ -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 */ diff --git a/src/concord-once.c b/src/concord-once.c index ed3a46ae5..5239c26a7 100644 --- a/src/concord-once.c +++ b/src/concord-once.c @@ -1,15 +1,29 @@ +#include #include #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; + ccord_has_sigint = 1; +} + CCORDcode ccord_global_init() { if (once) return CCORD_GLOBAL_INIT; + signal(SIGINT, &sigint_handler); + if (0 != curl_global_init(CURL_GLOBAL_DEFAULT)) { fprintf(stderr, "Couldn't start libcurl's globals\n"); return CCORD_GLOBAL_INIT; diff --git a/src/discord-client.c b/src/discord-client.c index f59842022..17fe21c19 100644 --- a/src/discord-client.c +++ b/src/discord-client.c @@ -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); @@ -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 From 068b21aa05ef47826a777ee5944176bfa8ad34d1 Mon Sep 17 00:00:00 2001 From: lcsmuller Date: Fri, 18 Mar 2022 19:21:19 -0300 Subject: [PATCH 2/6] chore(test/async.c): match d92f72 --- test/async.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test/async.c b/test/async.c index 174459812..3271f16fa 100644 --- a/test/async.c +++ b/test/async.c @@ -1,7 +1,6 @@ #include #include #include /* strcmp() */ -#include #include #include @@ -170,15 +169,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[]) { @@ -188,7 +178,6 @@ main(int argc, char *argv[]) else config_file = "../config.json"; - signal(SIGINT, &sigint_handler); ccord_global_init(); client = discord_config_init(config_file); From 17d3f1d6ffc981f969eb144336647315bca7d564 Mon Sep 17 00:00:00 2001 From: lcsmuller Date: Fri, 18 Mar 2022 19:24:17 -0300 Subject: [PATCH 3/6] chore(concord-once.h): typo --- include/concord-once.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/concord-once.h b/include/concord-once.h index 3476d68ea..90cb6e88c 100644 --- a/include/concord-once.h +++ b/include/concord-once.h @@ -12,7 +12,7 @@ * * 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 abruply. + * 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 */ From d6c77a608eb0bbc31e163035b269b4130b4766bf Mon Sep 17 00:00:00 2001 From: lcsmuller Date: Sat, 19 Mar 2022 10:36:26 -0300 Subject: [PATCH 4/6] feat(concord-once.c): assign a callback to SIGINT only if no prior assignments --- src/concord-once.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/concord-once.c b/src/concord-once.c index 5239c26a7..a8dace4ff 100644 --- a/src/concord-once.c +++ b/src/concord-once.c @@ -14,27 +14,30 @@ 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; - - signal(SIGINT, &sigint_handler); - - 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; } From 5c2cbaf6a00abc83f6d2287d964cafeadbe40dde Mon Sep 17 00:00:00 2001 From: lcsmuller Date: Sat, 19 Mar 2022 10:42:16 -0300 Subject: [PATCH 5/6] chore(examples|test): remove/replace redundant code --- examples/audit-log.c | 3 --- test/async.c | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/audit-log.c b/examples/audit-log.c index b07f2330c..05ebeaf2d 100644 --- a/examples/audit-log.c +++ b/examples/audit-log.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "discord.h" @@ -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"); diff --git a/test/async.c b/test/async.c index 3271f16fa..4450e98a7 100644 --- a/test/async.c +++ b/test/async.c @@ -6,8 +6,6 @@ #include "discord.h" -struct discord *client; - struct user_cxt { u64snowflake channel_id; unsigned long long counter; @@ -180,7 +178,7 @@ main(int argc, char *argv[]) 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 }; From 5c7c950542433bef4ccb3afa396d506266cc02c8 Mon Sep 17 00:00:00 2001 From: antropez Date: Sun, 20 Mar 2022 13:48:48 -0400 Subject: [PATCH 6/6] fix: fixed off-by-one error in carray.h --- core/third-party/carray.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/third-party/carray.h b/core/third-party/carray.h index 1553f2adb..0a14659a4 100644 --- a/core/third-party/carray.h +++ b/core/third-party/carray.h @@ -84,9 +84,9 @@ do { \ exit(EXIT_FAILURE); \ } \ \ + (carray)->size--; \ (location) = (carray)->array[(index)]; \ - memmove((carray)->array + index, (carray)->array + index + 1, sizeof(*(carray)->array) * (size_t) ((carray)->size - index)); \ - (carray)->size-- + memmove((carray)->array + index, (carray)->array + index + 1, sizeof(*(carray)->array) * (size_t) ((carray)->size - index)) /* carray_remove */ #define __carray_remove(carray, value, _type, _compare, _free) \ @@ -101,11 +101,11 @@ do { continue; \ \ _free; \ + (carray)->size--; \ memmove((carray)->array + __CARRAY_ITER_INDEX, \ (carray)->array + __CARRAY_ITER_INDEX + 1, \ sizeof(*(carray)->array) * (size_t) ((carray)->size - __CARRAY_ITER_INDEX)); \ \ - (carray)->size--; \ __CARRAY_ITER_INDEX = -1; \ break; \ } \