Skip to content

Commit

Permalink
Guard refresh memory leak fix against concurrency issues
Browse files Browse the repository at this point in the history
  • Loading branch information
UserNugget committed Jul 10, 2024
1 parent 5979db9 commit fab2948
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ public LimboImpl(LimboAPI plugin, VirtualWorld world) {
}

protected void refresh() {
this.localDispose();

this.built = true;
JoinGamePacket legacyJoinGame = this.createLegacyJoinGamePacket();
JoinGamePacket joinGame = this.createJoinGamePacket(ProtocolVersion.MINECRAFT_1_16);
Expand Down Expand Up @@ -351,7 +349,17 @@ private void addPostJoin(PreparedPacket packet) {
@Override
public void spawnPlayer(Player apiPlayer, LimboSessionHandler handler) {
if (!this.built) {
this.refresh();
List<PreparedPacket> packets = this.takeSnapshot();
try {
this.refresh();
} finally {
List<PreparedPacket> changed = this.takeSnapshot();
for (PreparedPacket packet : packets) {
if (packet != null && !changed.contains(packet)) {
packet.release();
}
}
}
}

ConnectedPlayer player = (ConnectedPlayer) apiPlayer;
Expand Down Expand Up @@ -730,19 +738,29 @@ public void dispose() {
}
}

private void localDispose() {
if (this.joinPackets == null) {
return;
private List<PreparedPacket> takeSnapshot() {
List<PreparedPacket> packets = new ArrayList<>();

packets.add(this.joinPackets);
packets.add(this.fastRejoinPackets);
packets.add(this.safeRejoinPackets);
packets.add(this.respawnPackets);
packets.add(this.firstChunks);
if (this.delayedChunks != null) {
packets.addAll(this.delayedChunks);
}
packets.add(this.configTransitionPackets);
packets.add(this.configPackets);

this.joinPackets.release();
this.fastRejoinPackets.release();
this.safeRejoinPackets.release();
this.respawnPackets.release();
this.firstChunks.release();
this.delayedChunks.forEach(PreparedPacket::release);
this.configTransitionPackets.release();
this.configPackets.release();
return packets;
}

private void localDispose() {
this.takeSnapshot().forEach(packet -> {
if (packet != null) {
packet.release();
}
});
}

// From Velocity.
Expand Down

0 comments on commit fab2948

Please sign in to comment.