diff --git a/src/main/java/net/minestom/server/acquirable/Acquirable.java b/src/main/java/net/minestom/server/acquirable/Acquirable.java index 1f0474944..a14c0c008 100644 --- a/src/main/java/net/minestom/server/acquirable/Acquirable.java +++ b/src/main/java/net/minestom/server/acquirable/Acquirable.java @@ -7,7 +7,6 @@ import net.minestom.server.utils.async.AsyncUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Stream; @@ -25,19 +24,12 @@ public interface Acquirable { * @return the entities ticked in the current thread */ static @NotNull Stream<@NotNull Entity> currentEntities() { - return AcquirableImpl.ENTRIES.get().stream() - .flatMap(chunkEntry -> chunkEntry.getEntities().stream()); - } - - /** - * Mostly for internal use, external calls are unrecommended as they could lead - * to unexpected behavior. - * - * @param entries the new chunk entries - */ - @ApiStatus.Internal - static void refreshEntries(@NotNull Collection entries) { - AcquirableImpl.ENTRIES.set(entries); + final Thread currentThread = Thread.currentThread(); + if (currentThread instanceof TickThread) { + return ((TickThread) currentThread).entries().stream() + .flatMap(chunkEntry -> chunkEntry.getEntities().stream()); + } + return Stream.empty(); } /** diff --git a/src/main/java/net/minestom/server/acquirable/AcquirableImpl.java b/src/main/java/net/minestom/server/acquirable/AcquirableImpl.java index 6855e1fee..6ac119ec1 100644 --- a/src/main/java/net/minestom/server/acquirable/AcquirableImpl.java +++ b/src/main/java/net/minestom/server/acquirable/AcquirableImpl.java @@ -1,17 +1,13 @@ package net.minestom.server.acquirable; -import net.minestom.server.thread.ThreadDispatcher; import net.minestom.server.thread.TickThread; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; final class AcquirableImpl implements Acquirable { - static final ThreadLocal> ENTRIES = ThreadLocal.withInitial(Collections::emptySet); static final AtomicLong WAIT_COUNTER_NANO = new AtomicLong(); /** @@ -40,8 +36,8 @@ final class AcquirableImpl implements Acquirable { static @Nullable ReentrantLock enter(@NotNull Thread currentThread, @Nullable TickThread elementThread) { if (elementThread == null) return null; if (currentThread == elementThread) return null; - final ReentrantLock currentLock = currentThread instanceof TickThread ? ((TickThread) currentThread).getLock() : null; - final ReentrantLock targetLock = elementThread.getLock(); + final ReentrantLock currentLock = currentThread instanceof TickThread ? ((TickThread) currentThread).lock() : null; + final ReentrantLock targetLock = elementThread.lock(); if (targetLock.isHeldByCurrentThread()) return null; // Monitoring diff --git a/src/main/java/net/minestom/server/thread/ThreadDispatcher.java b/src/main/java/net/minestom/server/thread/ThreadDispatcher.java index 2fa355de0..fb4d9ab8b 100644 --- a/src/main/java/net/minestom/server/thread/ThreadDispatcher.java +++ b/src/main/java/net/minestom/server/thread/ThreadDispatcher.java @@ -1,7 +1,6 @@ package net.minestom.server.thread; import net.minestom.server.MinecraftServer; -import net.minestom.server.acquirable.Acquirable; import net.minestom.server.entity.Entity; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; @@ -98,9 +97,9 @@ public final class ThreadDispatcher { // Execute tick this.phaser.register(); thread.startTick(() -> { - Acquirable.refreshEntries(chunkEntries); + thread.updateEntries(chunkEntries); - final ReentrantLock lock = thread.getLock(); + final ReentrantLock lock = thread.lock(); lock.lock(); for (ChunkEntry chunkEntry : chunkEntries) { final Chunk chunk = chunkEntry.chunk; diff --git a/src/main/java/net/minestom/server/thread/TickThread.java b/src/main/java/net/minestom/server/thread/TickThread.java index 475ed636e..f58c1f850 100644 --- a/src/main/java/net/minestom/server/thread/TickThread.java +++ b/src/main/java/net/minestom/server/thread/TickThread.java @@ -3,6 +3,8 @@ package net.minestom.server.thread; import net.minestom.server.MinecraftServer; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Collections; import java.util.concurrent.Phaser; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; @@ -18,6 +20,9 @@ public final class TickThread extends Thread { private volatile boolean stop; private Runnable tickRunnable; + private boolean isTicking; + private Collection entries; + public TickThread(Phaser phaser, int number) { super(MinecraftServer.THREAD_NAME_TICK + "-" + number); this.phaser = phaser; @@ -27,7 +32,9 @@ public final class TickThread extends Thread { public void run() { LockSupport.park(this); while (!stop) { + this.isTicking = true; this.tickRunnable.run(); + this.isTicking = false; this.phaser.arriveAndDeregister(); LockSupport.park(this); } @@ -38,12 +45,20 @@ public final class TickThread extends Thread { LockSupport.unpark(this); } + public Collection entries() { + return isTicking ? entries : Collections.emptyList(); + } + + void updateEntries(Collection entries) { + this.entries = entries; + } + /** * Gets the lock used to ensure the safety of entity acquisition. * * @return the thread lock */ - public @NotNull ReentrantLock getLock() { + public @NotNull ReentrantLock lock() { return lock; }