Make ClickCallbackProviderImpl thread-safe

Can no longer process tasks from the main thread like that anymore,
it just needs to be concurrent.
This commit is contained in:
Spottedleaf 2023-03-23 07:55:26 -07:00
parent d5b837c457
commit 6a5fff3caa
2 changed files with 68 additions and 5 deletions

View File

@ -1803,6 +1803,65 @@ index 4d9bc4a62ebae0f3707900503576c64733de639f..9ba89a4bf4ae4e42418eca18f9d8a109
this.queueIfAsyncOrRunImmediately(new Waitable<Void>() {
@Override
protected Void evaluate() {
diff --git a/src/main/java/io/papermc/paper/adventure/providers/ClickCallbackProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/ClickCallbackProviderImpl.java
index 3c17001bcd3862a76a22df488bff80a0ff4d1b83..b2fffaa862df045bacb346f3cbe7eb963e104e47 100644
--- a/src/main/java/io/papermc/paper/adventure/providers/ClickCallbackProviderImpl.java
+++ b/src/main/java/io/papermc/paper/adventure/providers/ClickCallbackProviderImpl.java
@@ -23,35 +23,42 @@ public class ClickCallbackProviderImpl implements ClickCallback.Provider {
public static final class CallbackManager {
- private final Map<UUID, StoredCallback> callbacks = new HashMap<>();
- private final Queue<StoredCallback> queue = new ConcurrentLinkedQueue<>();
+ private final java.util.concurrent.ConcurrentHashMap<UUID, StoredCallback> callbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Folia - region threading
+ // Folia - region threading
private CallbackManager() {
}
public UUID addCallback(final @NotNull ClickCallback<Audience> callback, final ClickCallback.@NotNull Options options) {
final UUID id = UUID.randomUUID();
- this.queue.add(new StoredCallback(callback, options, id));
+ final StoredCallback scb = new StoredCallback(callback, options, id); // Folia - region threading
+ this.callbacks.put(scb.id(), scb); // Folia - region threading
return id;
}
public void handleQueue(final int currentTick) {
// Evict expired entries
if (currentTick % 100 == 0) {
- this.callbacks.values().removeIf(callback -> !callback.valid());
+ this.callbacks.values().removeIf(StoredCallback::expired); // Folia - region threading - don't read uses field
}
- // Add entries from queue
- StoredCallback callback;
- while ((callback = this.queue.poll()) != null) {
- this.callbacks.put(callback.id(), callback);
- }
+ // Folia - region threading
}
public void runCallback(final @NotNull Audience audience, final UUID id) {
- final StoredCallback callback = this.callbacks.get(id);
- if (callback != null && callback.valid()) { //TODO Message if expired/invalid?
- callback.takeUse();
+ // Folia start - region threading
+ final StoredCallback[] use = new StoredCallback[1];
+ this.callbacks.computeIfPresent(id, (final UUID keyInMap, final StoredCallback value) -> {
+ if (!value.valid()) {
+ return null;
+ }
+ use[0] = value;
+ value.takeUse();
+ return value.valid() ? value : null;
+ });
+ final StoredCallback callback = use[0];
+ if (callback != null) { //TODO Message if expired/invalid?
+ // Folia end - region threading
callback.callback.accept(audience);
}
}
diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java
index 6df1948b1204a7288ecb7238b6fc2a733f7d25b3..6a413abc67aa4dcbab64231be3eb13446d5cc820 100644
--- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java
@ -3994,10 +4053,10 @@ index 0000000000000000000000000000000000000000..3549e5f3359f38b207e189d895954420
+}
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionisedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionisedServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b40d3834fbaa032fb5ee3a9423e1b4a7d3123c29
index 0000000000000000000000000000000000000000..4525ad9d0537406e2ca6ff8627d06c683e09a57a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionisedServer.java
@@ -0,0 +1,352 @@
@@ -0,0 +1,355 @@
+package io.papermc.paper.threadedregions;
+
+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
@ -4194,6 +4253,9 @@ index 0000000000000000000000000000000000000000..b40d3834fbaa032fb5ee3a9423e1b4a7
+
+ private void globalTick(final int tickCount) {
+ ++this.tickCount;
+ // expire invalid click command callbacks
+ io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue((int)this.tickCount);
+
+ // scheduler
+ ((FoliaGlobalRegionScheduler)Bukkit.getGlobalRegionScheduler()).tick();
+
@ -11530,7 +11592,7 @@ index d2f0a0755317f5fa9a1ccf7db346aa77fd287d80..b07df826a3028c14b48b09dbaeccc907
// CraftBukkit start - SPIGOT-5477, MC-142590
} else if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 8ccc92836bfda8e00eea649430174dcd5664af70..58eee2965ce3e92b0f90eb7e908c6eee40052670 100644
index 8ccc92836bfda8e00eea649430174dcd5664af70..6bf90c2a71d03788b6b15f858687372674dddc03 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -294,7 +294,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -11944,7 +12006,8 @@ index 8ccc92836bfda8e00eea649430174dcd5664af70..58eee2965ce3e92b0f90eb7e908c6eee
- this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
+ if (region == null) this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit // Folia - region threading - TODO REPLACE CRAFT SCHEDULER
MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
- io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
+ if (region == null) io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper
this.profiler.push("commandFunctions");
MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper
- this.getFunctions().tick();

View File

@ -10,7 +10,7 @@ the impact from scaling the region threads, but is not a fix
to the underlying issue.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 58eee2965ce3e92b0f90eb7e908c6eee40052670..81767d54db0109b78c7da2161d544537c6237d27 100644
index 6bf90c2a71d03788b6b15f858687372674dddc03..d9f6855ff7a70bf1e05e8cf93ed33c847c6c86e6 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2906,6 +2906,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa