From 777b696f3881d1d27dc6ba249bb904aff9b9e3da Mon Sep 17 00:00:00 2001 From: filoghost Date: Sat, 1 Oct 2022 16:27:24 +0200 Subject: [PATCH] Add more thread-safety checks --- .../api/current/DefaultHolographicDisplaysAPI.java | 2 -- .../core/api/v2/V2HologramsAPIProvider.java | 1 - .../core/base/BaseHologramManager.java | 9 +++++++++ .../core/listener/ChunkListener.java | 12 +++++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/api/current/DefaultHolographicDisplaysAPI.java b/core/src/main/java/me/filoghost/holographicdisplays/core/api/current/DefaultHolographicDisplaysAPI.java index e91ae9e9..5c366fa9 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/api/current/DefaultHolographicDisplaysAPI.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/api/current/DefaultHolographicDisplaysAPI.java @@ -39,7 +39,6 @@ class DefaultHolographicDisplaysAPI implements HolographicDisplaysAPI { public @NotNull Hologram createHologram(@NotNull Location location) { Preconditions.notNull(location, "location"); Preconditions.notNull(location.getWorld(), "location.getWorld()"); - Preconditions.checkMainThread("async hologram creation"); return apiHologramManager.createHologram(ImmutablePosition.of(location), plugin); } @@ -48,7 +47,6 @@ class DefaultHolographicDisplaysAPI implements HolographicDisplaysAPI { public @NotNull Hologram createHologram(@NotNull Position position) { Preconditions.notNull(position, "position"); Preconditions.notNull(position.getWorldName(), "position.getWorldName()"); - Preconditions.checkMainThread("async hologram creation"); return apiHologramManager.createHologram(ImmutablePosition.of(position), plugin); } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/api/v2/V2HologramsAPIProvider.java b/core/src/main/java/me/filoghost/holographicdisplays/core/api/v2/V2HologramsAPIProvider.java index 47c586f8..b5d2641a 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/api/v2/V2HologramsAPIProvider.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/api/v2/V2HologramsAPIProvider.java @@ -38,7 +38,6 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider { Preconditions.notNull(plugin, "plugin"); Preconditions.notNull(source, "source"); Preconditions.notNull(source.getWorld(), "source.getWorld()"); - Preconditions.checkMainThread("async hologram creation"); return hologramManager.createHologram(ImmutablePosition.of(source), plugin); } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/base/BaseHologramManager.java b/core/src/main/java/me/filoghost/holographicdisplays/core/base/BaseHologramManager.java index 6e295afb..d1c70606 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/base/BaseHologramManager.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/base/BaseHologramManager.java @@ -5,6 +5,7 @@ */ package me.filoghost.holographicdisplays.core.base; +import me.filoghost.fcommons.Preconditions; import org.bukkit.Chunk; import org.bukkit.World; @@ -20,6 +21,8 @@ public abstract class BaseHologramManager { private final List unmodifiableHologramsView = Collections.unmodifiableList(holograms); protected void addHologram(H hologram) { + Preconditions.checkMainThread("async hologram create"); + holograms.add(hologram); } @@ -28,11 +31,15 @@ public abstract class BaseHologramManager { } public void deleteHologram(H hologram) { + Preconditions.checkMainThread("async hologram delete"); + hologram.setDeleted(); holograms.remove(hologram); } public void deleteHologramsIf(Predicate condition) { + Preconditions.checkMainThread("async hologram delete"); + Iterator iterator = holograms.iterator(); while (iterator.hasNext()) { H hologram = iterator.next(); @@ -44,6 +51,8 @@ public abstract class BaseHologramManager { } public void deleteHolograms() { + Preconditions.checkMainThread("async hologram delete"); + Iterator iterator = holograms.iterator(); while (iterator.hasNext()) { H hologram = iterator.next(); diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/listener/ChunkListener.java b/core/src/main/java/me/filoghost/holographicdisplays/core/listener/ChunkListener.java index fc4be389..e90a3085 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/listener/ChunkListener.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/listener/ChunkListener.java @@ -48,6 +48,16 @@ public class ChunkListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onChunkUnload(ChunkUnloadEvent event) { Chunk chunk = event.getChunk(); + + // Always execute on the main thread + if (Bukkit.isPrimaryThread()) { + onChunkUnload(chunk); + } else { + Bukkit.getScheduler().runTask(plugin, () -> onChunkUnload(chunk)); + } + } + + private void onChunkUnload(Chunk chunk) { apiHologramManager.onChunkUnload(chunk); v2HologramManager.onChunkUnload(chunk); } @@ -61,7 +71,7 @@ public class ChunkListener implements Listener { return; } - // In case another plugin loads the chunk asynchronously, always make sure to load the holograms on the main thread + // Always execute on the main thread if (Bukkit.isPrimaryThread()) { onChunkLoad(chunk); } else {