From cb1b1b1673c8fdbf41e706f618255c00f2565731 Mon Sep 17 00:00:00 2001 From: "barryyt.cai.moxa" Date: Tue, 9 Dec 2025 11:51:38 +0800 Subject: [PATCH] fix: mutex deadlock when connection close --- broker/client.go | 14 ++++++++------ broker/comm.go | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/broker/client.go b/broker/client.go index c04e4fb..f56a2b2 100644 --- a/broker/client.go +++ b/broker/client.go @@ -828,11 +828,12 @@ func (c *client) Close() { Timestamp: time.Now().Unix(), }) - if c.mu.Lock(); c.conn != nil { + c.mu.Lock() + if c.conn != nil { _ = c.conn.Close() c.conn = nil - c.mu.Unlock() } + c.mu.Unlock() if b == nil { return @@ -905,13 +906,14 @@ func (c *client) WriterPacket(packet packets.ControlPacket) error { if packet == nil { return nil } - if c.conn == nil { - c.Close() - return errors.New("connect lost ....") - } c.mu.Lock() defer c.mu.Unlock() + + if c.conn == nil { + return errors.New("connect lost ....") + } + return packet.Write(c.conn) } diff --git a/broker/comm.go b/broker/comm.go index 45c8ecb..b7fa1c8 100644 --- a/broker/comm.go +++ b/broker/comm.go @@ -202,11 +202,13 @@ func (c *client) retryDelivery() { c.inflightMu.RLock() ilen := len(c.inflight) - if c.mu.Lock(); c.conn == nil || ilen == 0 { //Reset timer when client offline OR inflight is empty + c.mu.Lock() + if c.conn == nil || ilen == 0 { //Reset timer when client offline OR inflight is empty c.inflightMu.RUnlock() c.mu.Unlock() return } + c.mu.Unlock() // copy the to be retried elements out of the map to only hold the lock for a short time and use the new slice later to iterate // through them