From 64d55df21daee13681643cedd7cfc3ec4db6f234 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Thu, 28 Nov 2024 11:06:44 +0100 Subject: [PATCH] Don't endlessly wait on writer coroutine on disconnect --- lib/remote/jsonrpcconnection.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/remote/jsonrpcconnection.cpp b/lib/remote/jsonrpcconnection.cpp index e82d02a76d..c8a1c8f7d0 100644 --- a/lib/remote/jsonrpcconnection.cpp +++ b/lib/remote/jsonrpcconnection.cpp @@ -213,7 +213,17 @@ void JsonRpcConnection::Disconnect() IoEngine::SpawnCoroutine(m_IoStrand, [this, keepAlive](asio::yield_context yc) { m_OutgoingMessagesQueued.Set(); - m_WriterDone.Wait(yc); + { + asio::deadline_timer writerTimeout(m_IoStrand.context(), boost::posix_time::seconds(5)); + writerTimeout.async_wait(asio::bind_executor(m_IoStrand, [this](boost::system::error_code ec) { + if (!ec) { + m_WriterDone.Set(); + } + })); + + m_WriterDone.Wait(yc); + // We don't need to explicitly cancel the timer here; its destructor will handle it for us. + } /* * Do not swallow exceptions in a coroutine. @@ -228,6 +238,8 @@ void JsonRpcConnection::Disconnect() m_CheckLivenessTimer.cancel(); m_HeartbeatTimer.cancel(); + // In case the writer coroutine is not done yet which might got stuck somewhere in async_write + // or async_flush, cancel all operations on the underlying socket to unblock it. m_Stream->lowest_layer().cancel(ec); Timeout::Ptr shutdownTimeout (new Timeout(