From 642ca9c9dd98e84f41c6065efdcb7441ea4b4467 Mon Sep 17 00:00:00 2001 From: Josh Robson Chase Date: Thu, 4 Jan 2024 10:52:18 -0500 Subject: [PATCH] fix deadlock condition in onHeartbeat --- internal/tunnel/client/raw_session.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/internal/tunnel/client/raw_session.go b/internal/tunnel/client/raw_session.go index bc8d2979..36123043 100644 --- a/internal/tunnel/client/raw_session.go +++ b/internal/tunnel/client/raw_session.go @@ -278,24 +278,26 @@ func (s *rawSession) rpc(reqtype proto.ReqType, req any, resp any) error { } func (s *rawSession) onHeartbeat(pingTime time.Duration, timeout bool) { + if timeout { + s.Error("heartbeat timeout, terminating session") + s.Close() + return + } + // make sure we don't send on a closed channel. // Any number of `onHeartbeat` callbacks can be in flight at a given time, // but only one Close. s.closedLock.RLock() defer s.closedLock.RUnlock() + if s.closed { return } - if timeout { - s.Error("heartbeat timeout, terminating session") - s.Close() - } else { - s.Debug("heartbeat received", "latency_ms", int(pingTime.Milliseconds())) - select { - case s.latency <- pingTime: - default: - } + s.Debug("heartbeat received", "latency_ms", int(pingTime.Milliseconds())) + select { + case s.latency <- pingTime: + default: } }