Skip to content

Commit 04d4c83

Browse files
committed
Destroy rakPipeline() properly
1 parent 4d37bf1 commit 04d4c83

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

transport-raknet/src/main/java/org/cloudburstmc/netty/channel/raknet/RakServerChannel.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter;
3131
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRouteHandler;
3232
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerTailHandler;
33+
import org.cloudburstmc.netty.util.RakUtils;
3334

3435
import java.net.InetAddress;
3536
import java.net.InetSocketAddress;
@@ -91,13 +92,18 @@ public RakChildChannel getChildChannel(SocketAddress address) {
9192

9293
private void onChildClosed(ChannelFuture channelFuture) {
9394
RakChildChannel channel = (RakChildChannel) channelFuture.channel();
94-
channel.rakPipeline().fireChannelInactive();
95-
channel.rakPipeline().fireChannelUnregistered();
9695
this.childChannelMap.remove(channel.remoteAddress());
9796

9897
if (this.config().getMetrics() != null) {
9998
this.config().getMetrics().channelClose(channel.remoteAddress());
10099
}
100+
101+
channel.rakPipeline().fireChannelInactive();
102+
channel.rakPipeline().fireChannelUnregistered();
103+
// Need to use reflection to destroy pipeline because
104+
// DefaultChannelPipeline.destroy() is only called when channel.isOpen() is false,
105+
// but the method is called on parent channel, and there is no other way to destroy pipeline.
106+
RakUtils.destroyChannelPipeline(channel.rakPipeline());
101107
}
102108

103109
@Override

transport-raknet/src/main/java/org/cloudburstmc/netty/handler/codec/raknet/common/RakUnhandledMessagesQueue.java

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
4848
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
4949
if (this.future != null) {
5050
this.future.cancel(false);
51+
this.future = null;
5152
}
5253

5354
EncapsulatedPacket message;

transport-raknet/src/main/java/org/cloudburstmc/netty/util/RakUtils.java

+19
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@
1818

1919
import io.netty.buffer.ByteBuf;
2020
import io.netty.channel.Channel;
21+
import io.netty.channel.ChannelPipeline;
2122
import io.netty.channel.DefaultChannelPipeline;
2223

2324
import java.lang.reflect.Constructor;
2425
import java.lang.reflect.InvocationTargetException;
26+
import java.lang.reflect.Method;
2527
import java.net.*;
2628
import java.util.Queue;
2729

2830
public class RakUtils {
2931

3032
private static final Constructor<DefaultChannelPipeline> DEFAULT_CHANNEL_PIPELINE_CONSTRUCTOR;
33+
private static final Method PIPELINE_DESTROY_METHOD;
3134

3235
static {
3336
try {
@@ -37,6 +40,14 @@ public class RakUtils {
3740
} catch (NoSuchMethodException e) {
3841
throw new AssertionError("Unable to find DefaultChannelPipeline(Channel) constructor", e);
3942
}
43+
44+
try {
45+
Method method = DefaultChannelPipeline.class.getDeclaredMethod("destroy");
46+
method.setAccessible(true);
47+
PIPELINE_DESTROY_METHOD = method;
48+
} catch (NoSuchMethodException e) {
49+
throw new AssertionError("Unable to find DefaultChannelPipeline.destroy() method", e);
50+
}
4051
}
4152

4253
public static DefaultChannelPipeline newChannelPipeline(Channel channel) {
@@ -47,6 +58,14 @@ public static DefaultChannelPipeline newChannelPipeline(Channel channel) {
4758
}
4859
}
4960

61+
public static void destroyChannelPipeline(ChannelPipeline pipeline) {
62+
try {
63+
PIPELINE_DESTROY_METHOD.invoke(pipeline);
64+
} catch (IllegalAccessException | InvocationTargetException e) {
65+
throw new IllegalStateException("Unable to destroy DefaultChannelPipeline", e);
66+
}
67+
}
68+
5069
private static final int AF_INET6 = 23;
5170

5271
public static InetSocketAddress readAddress(ByteBuf buffer) {

0 commit comments

Comments
 (0)