Add proper thread safety. Please let me know if this deadlocks your server.

This commit is contained in:
md_5 2013-02-10 18:35:09 +11:00
parent 36f3a7a7f2
commit b7ffd83675

View file

@ -1,4 +1,4 @@
From 8794e1bc1ae9773a9f7c9943c7696a76e66691aa Mon Sep 17 00:00:00 2001 From 2624cc163bed8a94b851c7dbc186a304ce63bff7 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au> From: md_5 <md_5@live.com.au>
Date: Sun, 3 Feb 2013 10:24:33 +1100 Date: Sun, 3 Feb 2013 10:24:33 +1100
Subject: [PATCH] Netty Subject: [PATCH] Netty
@ -17,13 +17,13 @@ This commit is licensed under the Creative Commons Attribution-ShareAlike 3.0 Un
.../net/minecraft/server/PendingConnection.java | 15 +- .../net/minecraft/server/PendingConnection.java | 15 +-
.../net/minecraft/server/PlayerConnection.java | 2 +- .../net/minecraft/server/PlayerConnection.java | 2 +-
src/main/java/org/spigotmc/netty/CipherCodec.java | 65 ++++++ src/main/java/org/spigotmc/netty/CipherCodec.java | 65 ++++++
.../org/spigotmc/netty/NettyNetworkManager.java | 211 ++++++++++++++++++ .../org/spigotmc/netty/NettyNetworkManager.java | 221 ++++++++++++++++++
.../org/spigotmc/netty/NettyServerConnection.java | 105 +++++++++ .../org/spigotmc/netty/NettyServerConnection.java | 105 +++++++++
.../org/spigotmc/netty/NettySocketAdaptor.java | 248 +++++++++++++++++++++ .../org/spigotmc/netty/NettySocketAdaptor.java | 248 +++++++++++++++++++++
.../java/org/spigotmc/netty/PacketDecoder.java | 47 ++++ .../java/org/spigotmc/netty/PacketDecoder.java | 47 ++++
.../java/org/spigotmc/netty/PacketEncoder.java | 43 ++++ .../java/org/spigotmc/netty/PacketEncoder.java | 43 ++++
.../java/org/spigotmc/netty/PacketListener.java | 100 +++++++++ .../java/org/spigotmc/netty/PacketListener.java | 100 +++++++++
11 files changed, 841 insertions(+), 7 deletions(-) 11 files changed, 851 insertions(+), 7 deletions(-)
create mode 100644 src/main/java/org/spigotmc/netty/CipherCodec.java create mode 100644 src/main/java/org/spigotmc/netty/CipherCodec.java
create mode 100644 src/main/java/org/spigotmc/netty/NettyNetworkManager.java create mode 100644 src/main/java/org/spigotmc/netty/NettyNetworkManager.java
create mode 100644 src/main/java/org/spigotmc/netty/NettyServerConnection.java create mode 100644 src/main/java/org/spigotmc/netty/NettyServerConnection.java
@ -208,10 +208,10 @@ index 0000000..cfc0535
+} +}
diff --git a/src/main/java/org/spigotmc/netty/NettyNetworkManager.java b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java diff --git a/src/main/java/org/spigotmc/netty/NettyNetworkManager.java b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
new file mode 100644 new file mode 100644
index 0000000..effd1ee index 0000000..81aa42e
--- /dev/null --- /dev/null
+++ b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java +++ b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
@@ -0,0 +1,211 @@ @@ -0,0 +1,221 @@
+package org.spigotmc.netty; +package org.spigotmc.netty;
+ +
+import io.netty.channel.Channel; +import io.netty.channel.Channel;
@ -247,8 +247,9 @@ index 0000000..effd1ee
+ private static final PrivateKey key = server.F().getPrivate(); + private static final PrivateKey key = server.F().getPrivate();
+ private static final NettyServerConnection serverConnection = (NettyServerConnection) server.ae(); + private static final NettyServerConnection serverConnection = (NettyServerConnection) server.ae();
+ /*========================================================================*/ + /*========================================================================*/
+ private Queue<Packet> syncPackets = new ConcurrentLinkedQueue<Packet>(); + private final Object mutex = new Object();
+ private volatile Channel channel; + private final Queue<Packet> syncPackets = new ConcurrentLinkedQueue<Packet>();
+ private Channel channel;
+ private SocketAddress address; + private SocketAddress address;
+ private Connection handler; + private Connection handler;
+ private SecretKey secret; + private SecretKey secret;
@ -258,6 +259,7 @@ index 0000000..effd1ee
+ +
+ @Override + @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ synchronized (mutex) {
+ // Channel and address groundwork first + // Channel and address groundwork first
+ channel = ctx.channel(); + channel = ctx.channel();
+ address = channel.remoteAddress(); + address = channel.remoteAddress();
@ -268,18 +270,22 @@ index 0000000..effd1ee
+ // Finally register the connection + // Finally register the connection
+ serverConnection.pendingConnections.add((PendingConnection) handler); + serverConnection.pendingConnections.add((PendingConnection) handler);
+ } + }
+ }
+ +
+ @Override + @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ synchronized (mutex) {
+ if (dcReason == null || dcArgs == null) { + if (dcReason == null || dcArgs == null) {
+ a("disconnect.endOfStream", new Object[0]); + a("disconnect.endOfStream", new Object[0]);
+ } + }
+ // Remove channel reference to indicate we are done + // Remove channel reference to indicate we are done
+ channel = null; + channel = null;
+ } + }
+ }
+ +
+ @Override + @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ synchronized (mutex) {
+ // TODO: Remove this once we are more stable + // TODO: Remove this once we are more stable
+ // Bukkit.getServer().getLogger().severe("======================= Start Netty Debug Log ======================="); + // Bukkit.getServer().getLogger().severe("======================= Start Netty Debug Log =======================");
+ // Bukkit.getServer().getLogger().log(Level.SEVERE, "Error caught whilst handling " + channel, cause); + // Bukkit.getServer().getLogger().log(Level.SEVERE, "Error caught whilst handling " + channel, cause);
@ -288,6 +294,7 @@ index 0000000..effd1ee
+ // Disconnect with generic reason + exception + // Disconnect with generic reason + exception
+ a("disconnect.genericReason", new Object[]{"Internal exception: " + cause}); + a("disconnect.genericReason", new Object[]{"Internal exception: " + cause});
+ } + }
+ }
+ +
+ @Override + @Override
+ public void messageReceived(ChannelHandlerContext ctx, final Packet msg) throws Exception { + public void messageReceived(ChannelHandlerContext ctx, final Packet msg) throws Exception {
@ -329,6 +336,7 @@ index 0000000..effd1ee
+ * @param packet the packet to queue + * @param packet the packet to queue
+ */ + */
+ public void queue(Packet packet) { + public void queue(Packet packet) {
+ synchronized (mutex) {
+ // Only send if channel is still connected + // Only send if channel is still connected
+ if (channel != null) { + if (channel != null) {
+ // Process packet via handler + // Process packet via handler
@ -342,8 +350,6 @@ index 0000000..effd1ee
+ BufferedBlockCipher encrypt = NettyServerConnection.getCipher(true, secret); + BufferedBlockCipher encrypt = NettyServerConnection.getCipher(true, secret);
+ BufferedBlockCipher decrypt = NettyServerConnection.getCipher(false, secret); + BufferedBlockCipher decrypt = NettyServerConnection.getCipher(false, secret);
+ CipherCodec codec = new CipherCodec(encrypt, decrypt); + CipherCodec codec = new CipherCodec(encrypt, decrypt);
+ // Only add if the channel hasn't disconnected in the meantime
+ if (channel != null) {
+ channel.pipeline().addBefore("decoder", "cipher", codec); + channel.pipeline().addBefore("decoder", "cipher", codec);
+ } + }
+ } + }
@ -392,10 +398,12 @@ index 0000000..effd1ee
+ * close. Close and release all resources associated with this connection. + * close. Close and release all resources associated with this connection.
+ */ + */
+ public void d() { + public void d() {
+ synchronized (mutex) {
+ if (channel != null) { + if (channel != null) {
+ channel.close(); + channel.close();
+ } + }
+ } + }
+ }
+ +
+ /** + /**
+ * queueSize. Return the number of packets in the low priority queue. In a + * queueSize. Return the number of packets in the low priority queue. In a
@ -416,12 +424,14 @@ index 0000000..effd1ee
+ * exception which triggered the disconnect. + * exception which triggered the disconnect.
+ */ + */
+ public void a(String reason, Object... arguments) { + public void a(String reason, Object... arguments) {
+ synchronized (mutex) {
+ if (channel != null) { + if (channel != null) {
+ dcReason = reason; + dcReason = reason;
+ dcArgs = arguments; + dcArgs = arguments;
+ channel.close(); + channel.close();
+ } + }
+ } + }
+ }
+} +}
diff --git a/src/main/java/org/spigotmc/netty/NettyServerConnection.java b/src/main/java/org/spigotmc/netty/NettyServerConnection.java diff --git a/src/main/java/org/spigotmc/netty/NettyServerConnection.java b/src/main/java/org/spigotmc/netty/NettyServerConnection.java
new file mode 100644 new file mode 100644