I'm sure these variables have other names internal to minecraft, but i'll refer to them by their MCP name.
readPacketCache is a synchronized array list. Items are removed from it in a read function by readPacketCache.remove(0). This a) blocks all access to the object and b) causes every element to be copied into a lower index, making this an order N operation.
This makes reading N items from the "queue" an O(N^2) operation, holding a lock for each O(N) operation.
This means that under high load, insert to the queue is an O(N) operation, with a high overhead, while it waits for the lock.
the java concurrentLinkedQueue is an unbounded queue designed for exactly this situation with constant time, lock-free push/pull concurrently (several threads can push and pull at the same time without causing any of them to block).
Changing this code does not cause any other code to need to be changed, as it is a private variable, and INetworkManager's are ALWAYS accessed via their interface, because it could be a Memory or a TCP connection, and the code doesn't know which.
this is cross-posted as a patch to fml - https://github.com/MinecraftForge/FML/issues/189
I have tested this in my MCP install, with both buildcraft and other mods active, with no problems.
package net.minecraft.network;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet;
public class MemoryConnection implements INetworkManager
{
private static final SocketAddress mySocketAddress = new InetSocketAddress("127.0.0.1", 0);
private final Queue<Packet> readPacketCache = new ConcurrentLinkedQueue<Packet>();
private MemoryConnection pairedConnection;
private NetHandler myNetHandler;
/** set to true by {server,network}Shutdown */
private boolean shuttingDown = false;
private String shutdownReason = "";
private Object[] field_74439_g;
private boolean gamePaused = false;
<snip - unchanged functions removed>
/**
* Checks timeouts and processes all pending read packets.
*/
public void processReadPackets()
{
int var1 = 2500;
while (var1-- >= 0 && !this.readPacketCache.isEmpty())
{
Packet var2 = this.readPacketCache.poll();
var2.processPacket(this.myNetHandler);
}
if (this.readPacketCache.size() > var1)
{
System.out.println("Memory connection overburdened; after processing 2500 packets, we still have " + this.readPacketCache.size() + " to go!");
}
if (this.shuttingDown && this.readPacketCache.isEmpty())
{
this.myNetHandler.handleErrorMessage(this.shutdownReason, this.field_74439_g);
}
}
<snip - more unchanged functions removed>
}
--
@@ -7,7 +7,7 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet;
@@ -16,5 +16,5 @@
{
private static final SocketAddress mySocketAddress = new InetSocketAddress("127.0.0.1", 0);
- private final List readPacketCache = Collections.synchronizedList(new ArrayList());
+ private final Queue<Packet> readPacketCache = new ConcurrentLinkedQueue<Packet>();
private MemoryConnection pairedConnection;
private NetHandler myNetHandler;
@@ -77,5 +77,5 @@
while (var1-- >= 0 && !this.readPacketCache.isEmpty())
{
- Packet var2 = (Packet)this.readPacketCache.remove(0);
+ Packet var2 = this.readPacketCache.poll();
var2.processPacket(this.myNetHandler);
}
Related issues
Comments
Also, this is a feature request, technically. Not a bug.

Not a feature request. Feature request is intended to change the functionality. This suggestion intends to improve a very bad implementation without any change to functionality.
This as close to a bug one can get without it being fully one. Lets just say, one would not pass the relevant exercise in university programming course if this mistake had been done.
In addition to wrapping the code inside {code}, I'd add a significant missing info in the begin of the descriptions: "readPacketCache is a synchronized array list".
Ok fine, but this still isn't a bug. A bug is something that is broken about the game, not something that is badly implemented. This site is for bugs. In fact, you labeled it as a bug!
Also, the {noformat} tags don't turn it into an IDE like environment, all it does is make it so that Tabs are actually tabs, not bullet points.
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
Really? Using third-party programs in your "fix" code? C'mon, man!
EDIT:
I will respect this so-called "bug" post once I don't see Forge ModLoader referenced.

Wrapped the code with
.
But in the sense of this bug tracker, this is no bug, thus invalid.
@Dean Baset - i have removed all non-relevent code; that code was present in the full source i showed; that is because, as a non-minecraft dev, that is all i have easy access to, and this started as a cross-post from the FML github.
That was why I also posted the patch, which is a 5 line change which, other than variable names, would apply straight to vanilla code.
@Kumasasa - where would be the appropriate place to raise an issue like this? (also, this implies that you do not consider easily fixed excessive cpu usage a bug?)

Reopened.
Technically still not a bug, but now your change is small enough that a dev can look at it.

Pretty sure performance issues due to poor implementation qualifies as a bug. In the case of this issue in particular, fixing it may help with some of the ghosting or desynch type of issues people keep encountering.

Still valid for 1.5 (has the same piece of code).
Is this still a concern in the current Minecraft version 14w11b / Launcher version 1.3.11 or later? If so, please update the affected versions in order to best aid Mojang ensuring bugs are still valid in the latest releases/pre-releases.

Considering that there is now another bug for getting exceptions with single player mode, apparently caused by firewall blocking localhost connection, it would seem that the memory connection might not be currently used. However, I haven't checked this assumption. And without access to an up to date MCP, I can not confirm the situation in any meaningful way. (Or well, I could, but it would take hours, while Mojang could both check and fix this in less than few minutes... so... yeah, better ask Mojang about the status.)

Is this still a concern in the current Minecraft version 1.8.1 Prerelease 3 / Launcher version 1.5.3 or later? If so, please update the affected versions in order to best aid Mojang ensuring bugs are still valid in the latest releases/pre-releases.
No response for over a year.
Please put the code in {noformat}