Opaque ordering for LazyPacket

This commit is contained in:
themode 2022-01-01 03:54:37 +01:00 committed by TheMode
parent 10d40dd19d
commit b79054f8e8
2 changed files with 18 additions and 3 deletions

View File

@ -31,6 +31,7 @@ public final class CachedPacket implements SendablePacket {
} }
private final Supplier<ServerPacket> packetSupplier; private final Supplier<ServerPacket> packetSupplier;
@SuppressWarnings("unused")
private SoftReference<FramedPacket> packet; private SoftReference<FramedPacket> packet;
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) { public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {

View File

@ -3,6 +3,8 @@ package net.minestom.server.network.packet.server;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
@ -12,20 +14,32 @@ import java.util.function.Supplier;
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public final class LazyPacket implements SendablePacket { public final class LazyPacket implements SendablePacket {
private static final VarHandle PACKET;
static {
try {
PACKET = MethodHandles.lookup().findVarHandle(LazyPacket.class, "packet", ServerPacket.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
private final Supplier<ServerPacket> packetSupplier; private final Supplier<ServerPacket> packetSupplier;
private volatile ServerPacket packet; @SuppressWarnings("unused")
private ServerPacket packet;
public LazyPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) { public LazyPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
this.packetSupplier = packetSupplier; this.packetSupplier = packetSupplier;
} }
public @NotNull ServerPacket packet() { public @NotNull ServerPacket packet() {
ServerPacket packet = this.packet; ServerPacket packet = (ServerPacket) PACKET.getOpaque(this);
if (packet == null) { if (packet == null) {
synchronized (this) { synchronized (this) {
packet = this.packet; packet = this.packet;
if (packet == null) { if (packet == null) {
packet = this.packet = packetSupplier.get(); packet = packetSupplier.get();
PACKET.setOpaque(this, packet);
} }
} }
} }