From dd47c7c66dd235d0ac96768337b4769e7245fe56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 16 Nov 2018 19:41:49 +0100 Subject: [PATCH] Improve handling of disconnects and reconnects (#228) * Check response 0 on disconnect From recv(): The return value will be 0 when the peer has performed an orderly shutdown * Add persistent presence and handlers * Use buffer instead of raw struct * Clear presence data on shutdown * Remove CurrentPresence and add boolean instead This removes the need for having 2 big buffers in favor of using a small boolean --- src/connection_unix.cpp | 3 +++ src/discord_rpc.cpp | 16 ++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/connection_unix.cpp b/src/connection_unix.cpp index 6fe359e..85dace3 100644 --- a/src/connection_unix.cpp +++ b/src/connection_unix.cpp @@ -118,5 +118,8 @@ bool BaseConnection::Read(void* data, size_t length) } Close(); } + else if (res == 0) { + Close(); + } return res == (int)length; } diff --git a/src/discord_rpc.cpp b/src/discord_rpc.cpp index 2e44c93..0392453 100644 --- a/src/discord_rpc.cpp +++ b/src/discord_rpc.cpp @@ -54,6 +54,7 @@ static std::atomic_bool WasJustDisconnected{false}; static std::atomic_bool GotErrorMessage{false}; static std::atomic_bool WasJoinGame{false}; static std::atomic_bool WasSpectateGame{false}; +static std::atomic_bool UpdatePresence{false}; static char JoinGameSecret[256]; static char SpectateGameSecret[256]; static int LastErrorCode{0}; @@ -214,17 +215,17 @@ static void Discord_UpdateConnection(void) } // writes - if (QueuedPresence.length) { + if (UpdatePresence.exchange(false) && QueuedPresence.length) { QueuedMessage local; { std::lock_guard guard(PresenceMutex); local.Copy(QueuedPresence); - QueuedPresence.length = 0; } if (!Connection->Write(local.buffer, local.length)) { // if we fail to send, requeue std::lock_guard guard(PresenceMutex); QueuedPresence.Copy(local); + UpdatePresence.exchange(true); } } @@ -310,6 +311,10 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, Connection = RpcConnection::Create(applicationId); Connection->onConnect = [](JsonDocument& readyMessage) { Discord_UpdateHandlers(&QueuedHandlers); + if (QueuedPresence.length > 0) { + UpdatePresence.exchange(true); + SignalIOActivity(); + } auto data = GetObjMember(&readyMessage, "data"); auto user = GetObjMember(data, "user"); auto userId = GetStrMember(user, "id"); @@ -335,10 +340,6 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, Connection->onDisconnect = [](int err, const char* message) { LastDisconnectErrorCode = err; StringCopy(LastDisconnectErrorMessage, message); - { - std::lock_guard guard(HandlerMutex); - Handlers = {}; - } WasJustDisconnected.exchange(true); UpdateReconnectTime(); }; @@ -354,6 +355,8 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void) Connection->onConnect = nullptr; Connection->onDisconnect = nullptr; Handlers = {}; + QueuedPresence.length = 0; + UpdatePresence.exchange(false); if (IoThread != nullptr) { IoThread->Stop(); delete IoThread; @@ -369,6 +372,7 @@ extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* std::lock_guard guard(PresenceMutex); QueuedPresence.length = JsonWriteRichPresenceObj( QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); + UpdatePresence.exchange(true); } SignalIOActivity(); }