From 9115d662d0495d3d6269e7825ec829bd6d38dfcf Mon Sep 17 00:00:00 2001 From: sheep_yan <313169664@qq.com> Date: Thu, 18 Jul 2024 13:53:48 +0800 Subject: [PATCH] [ISSUE #8366] Eliminate deadlocks during the client shutdown process. (#8367) * [ISSUE #8366] When determining if `ChannelWrapper` is the wrapper for a channel, no longer acquire a read lock. * [ISSUE #8366] Compare channels for equality using `isWrapperOf`. --- .../remoting/netty/NettyRemotingClient.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java index 1d595f32b9a..41976122b2f 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java @@ -421,7 +421,7 @@ public void closeChannel(final String addr, final Channel channel) { if (null == prevCW) { LOGGER.info("closeChannel: the channel[{}] has been removed from the channel table before", addrRemote); removeItemFromTable = false; - } else if (prevCW.getChannel() != channel) { + } else if (prevCW.isWrapperOf(channel)) { LOGGER.info("closeChannel: the channel[{}] has been closed before, and has been created again, nothing to do.", addrRemote); removeItemFromTable = false; @@ -463,12 +463,10 @@ public void closeChannel(final Channel channel) { for (Map.Entry entry : channelTables.entrySet()) { String key = entry.getKey(); ChannelWrapper prev = entry.getValue(); - if (prev.getChannel() != null) { - if (prev.getChannel() == channel) { - prevCW = prev; - addrRemote = key; - break; - } + if (prev.isWrapperOf(channel)) { + prevCW = prev; + addrRemote = key; + break; } } @@ -1022,6 +1020,13 @@ public boolean isWritable() { return getChannel().isWritable(); } + public boolean isWrapperOf(Channel channel) { + if (this.channelFuture.channel() != null && this.channelFuture.channel() == channel) { + return true; + } + return false; + } + private Channel getChannel() { return getChannelFuture().channel(); }