From de817e5e528b51da12b847d5649c759dadc1a3b8 Mon Sep 17 00:00:00 2001 From: themode Date: Sat, 1 Jan 2022 16:17:47 +0100 Subject: [PATCH] Use acquire/release for node updating --- .../minestom/server/event/EventNodeImpl.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/minestom/server/event/EventNodeImpl.java b/src/main/java/net/minestom/server/event/EventNodeImpl.java index c1d78d82c..261a31ab4 100644 --- a/src/main/java/net/minestom/server/event/EventNodeImpl.java +++ b/src/main/java/net/minestom/server/event/EventNodeImpl.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -229,7 +231,7 @@ non-sealed class EventNodeImpl implements EventNode { private void invalidateEvent(Class eventClass) { forTargetEvents(eventClass, type -> { Handle handle = handleMap.get(type); - if (handle != null) handle.updated = false; + if (handle != null) Handle.UPDATED.setRelease(handle, false); }); final EventNodeImpl parent = this.parent; if (parent != null) parent.invalidateEvent(eventClass); @@ -260,10 +262,21 @@ non-sealed class EventNodeImpl implements EventNode { } static final class Handle implements ListenerHandle { + private static final VarHandle UPDATED; + + static { + try { + UPDATED = MethodHandles.lookup().findVarHandle(Handle.class, "updated", boolean.class); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + private final EventNodeImpl node; private final Class eventType; private Consumer listener = null; - private volatile boolean updated; + @SuppressWarnings("unused") + private boolean updated; // Use the UPDATED var handle Handle(EventNodeImpl node, Class eventType) { this.node = node; @@ -287,12 +300,12 @@ non-sealed class EventNodeImpl implements EventNode { } @Nullable Consumer updatedListener() { - if (updated) return listener; + if ((boolean) UPDATED.getAcquire(this)) return listener; synchronized (GLOBAL_CHILD_LOCK) { - if (updated) return listener; + if ((boolean) UPDATED.getAcquire(this)) return listener; final Consumer listener = createConsumer(); this.listener = listener; - this.updated = true; + UPDATED.setRelease(this, true); return listener; } } @@ -433,7 +446,7 @@ non-sealed class EventNodeImpl implements EventNode { EventListener.Result result = listener.run(event); if (result == EventListener.Result.EXPIRED) { node.removeListener(listener); - this.updated = false; + UPDATED.setRelease(this, false); } } }