From 0b7a72ae0ea25532e002dd25245e39ca4343a5a3 Mon Sep 17 00:00:00 2001 From: Stefan Wasilewski Date: Sun, 20 Sep 2026 02:20:33 +0400 Subject: [PATCH] fix connect timeout deadlock --- src/lib/net/SecureSocket.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 78290309e..8befd7add 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -380,13 +380,22 @@ void SecureSocket::createSSL() void SecureSocket::freeSSL() { - std::scoped_lock ssl_lock{ssl_mutex_}; - isFatal(true); + // take socket from multiplexer ASAP otherwise the race condition // could cause events to get called on a dead object. TCPSocket - // will do this, too, but the double-call is harmless + // will do this, too, but the double-call is harmless. + // + // this must happen *before* ssl_mutex_ is taken. the multiplexer holds its + // job list across job->run(), and secureAccept()/secureConnect() take + // ssl_mutex_ from inside a job, so taking ssl_mutex_ here first and then + // waiting on the job list inverts the lock order against the multiplexer + // thread and hangs both. removeSocket() also returns only once no job is + // running, so the teardown below still cannot race a live job. setJob(nullptr); + + std::scoped_lock ssl_lock{ssl_mutex_}; + if (m_ssl) { if (m_ssl->m_ssl != nullptr) { SSL_set_quiet_shutdown(m_ssl->m_ssl, 1);