mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-08 03:40:27 +01:00
Use opaque memory ordering for cached packets
This commit is contained in:
parent
4b89ce33ee
commit
10d40dd19d
@ -5,9 +5,10 @@ import org.jetbrains.annotations.ApiStatus;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.VarHandle;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,12 +20,17 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public final class CachedPacket implements SendablePacket {
|
public final class CachedPacket implements SendablePacket {
|
||||||
private static final AtomicIntegerFieldUpdater<CachedPacket> UPDATER =
|
private static final VarHandle PACKET;
|
||||||
AtomicIntegerFieldUpdater.newUpdater(CachedPacket.class, "updated");
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
PACKET = MethodHandles.lookup().findVarHandle(CachedPacket.class, "packet", SoftReference.class);
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Supplier<ServerPacket> packetSupplier;
|
private final Supplier<ServerPacket> packetSupplier;
|
||||||
// 0 means that the reference needs to be updated
|
|
||||||
// Anything else (currently 1) means that the packet is up-to-date
|
|
||||||
private volatile int updated = 0;
|
|
||||||
private SoftReference<FramedPacket> packet;
|
private SoftReference<FramedPacket> packet;
|
||||||
|
|
||||||
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
|
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
|
||||||
@ -36,12 +42,14 @@ public final class CachedPacket implements SendablePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
this.updated = 0;
|
PACKET.setOpaque(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull ServerPacket packet() {
|
public @NotNull ServerPacket packet() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
SoftReference<FramedPacket> ref = (SoftReference<FramedPacket>) PACKET.getOpaque(this);
|
||||||
FramedPacket cache;
|
FramedPacket cache;
|
||||||
if (updated == 1 && (cache = packet.get()) != null)
|
if (ref != null && (cache = ref.get()) != null)
|
||||||
return cache.packet(); // Avoid potential packet allocation
|
return cache.packet(); // Avoid potential packet allocation
|
||||||
return packetSupplier.get();
|
return packetSupplier.get();
|
||||||
}
|
}
|
||||||
@ -54,12 +62,12 @@ public final class CachedPacket implements SendablePacket {
|
|||||||
private @Nullable FramedPacket updatedCache() {
|
private @Nullable FramedPacket updatedCache() {
|
||||||
if (!PacketUtils.CACHED_PACKET)
|
if (!PacketUtils.CACHED_PACKET)
|
||||||
return null;
|
return null;
|
||||||
SoftReference<FramedPacket> ref;
|
@SuppressWarnings("unchecked")
|
||||||
|
SoftReference<FramedPacket> ref = (SoftReference<FramedPacket>) PACKET.getOpaque(this);
|
||||||
FramedPacket cache;
|
FramedPacket cache;
|
||||||
if (updated == 0 || ((ref = packet) == null || (cache = ref.get()) == null)) {
|
if (ref == null || (cache = ref.get()) == null) {
|
||||||
cache = PacketUtils.allocateTrimmedPacket(packetSupplier.get());
|
cache = PacketUtils.allocateTrimmedPacket(packetSupplier.get());
|
||||||
this.packet = new SoftReference<>(cache);
|
PACKET.setOpaque(this, new SoftReference<>(cache));
|
||||||
UPDATER.compareAndSet(this, 0, 1);
|
|
||||||
}
|
}
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user