Skip to content

Commit 856ea1c

Browse files
committed
fix spark & fix #11
1 parent ae0f77b commit 856ea1c

2 files changed

Lines changed: 174 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: bea4dev <bea0224@outlook.jp>
3+
Date: Mon, 13 Jan 2025 05:17:57 +0900
4+
Subject: [PATCH] fix spark
5+
6+
7+
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
8+
index ab84c9697bc3bbe05d20149005b894916564ab3b..1d442a245fdaca70eb9ffd9059a262d31da2662c 100644
9+
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
10+
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
11+
@@ -479,6 +479,7 @@ public final class CraftServer implements Server {
12+
}
13+
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
14+
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
15+
+ world.chiyogami.thread.WorldThreadPool.init();
16+
this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark
17+
}
18+
19+
diff --git a/src/main/java/world/chiyogami/thread/WorldThreadPool.java b/src/main/java/world/chiyogami/thread/WorldThreadPool.java
20+
index e11677b2741a9650fce512bf6e3d0f8017f752c0..ff14d4a3c73eb1f58615695b600b77371069b354 100644
21+
--- a/src/main/java/world/chiyogami/thread/WorldThreadPool.java
22+
+++ b/src/main/java/world/chiyogami/thread/WorldThreadPool.java
23+
@@ -2,21 +2,22 @@ package world.chiyogami.thread;
24+
25+
import ca.spottedleaf.moonrise.common.util.TickThread;
26+
import net.minecraft.server.level.ServerLevel;
27+
+import world.chiyogami.config.ChiyogamiConfig;
28+
29+
import java.util.*;
30+
import java.util.concurrent.*;
31+
import java.util.concurrent.atomic.AtomicInteger;
32+
import java.util.concurrent.locks.ReentrantLock;
33+
+import java.util.stream.IntStream;
34+
35+
public class WorldThreadPool {
36+
37+
private static ExecutorService executorService = null;
38+
+ public static Set<Thread> allThreads = ConcurrentHashMap.newKeySet();
39+
40+
private static int maxPoolSize = 0;
41+
42+
private static int previousPoolSize = 0;
43+
-
44+
- private static final AtomicInteger threadCount = new AtomicInteger(0);
45+
46+
public static void setMaxPoolSize(int poolSize) {WorldThreadPool.maxPoolSize = poolSize;}
47+
48+
@@ -36,6 +37,28 @@ public class WorldThreadPool {
49+
WORLD_THREAD_HASH_MAP_LOCK.unlock();
50+
}
51+
}
52+
+
53+
+ public static void init() {
54+
+ int poolSize = ChiyogamiConfig.getMaxWorldThreads();
55+
+ if (poolSize == 0) {
56+
+ poolSize = 4;
57+
+ }
58+
+
59+
+ AtomicInteger threadCount = new AtomicInteger(0);
60+
+
61+
+ executorService = Executors.newFixedThreadPool(poolSize, runnable -> {
62+
+ Thread thread = new TickThread(runnable, "WorldTickThread[" + threadCount.getAndIncrement() + "]");
63+
+ allThreads.add(thread);
64+
+ return thread;
65+
+ });
66+
+ // create all thread
67+
+ Callable<Void> callable = () -> null;
68+
+ try {
69+
+ executorService.invokeAll(IntStream.range(0, poolSize).mapToObj(i -> callable).toList());
70+
+ } catch (InterruptedException e) {
71+
+ throw new RuntimeException(e);
72+
+ }
73+
+ }
74+
75+
public static boolean isWorldThread() {
76+
return worldThreadHashMap.containsKey(Thread.currentThread());
77+
@@ -51,17 +74,6 @@ public class WorldThreadPool {
78+
public static void shutdown(){if(executorService != null) executorService.shutdown();}
79+
80+
public static void doTick(Collection<ServerLevel> serverLevels){
81+
- int pool = maxPoolSize > 0 ? maxPoolSize : serverLevels.size();
82+
-
83+
- if(pool != previousPoolSize){
84+
- if(executorService != null) executorService.shutdown();
85+
- executorService = Executors.newFixedThreadPool(pool, runnable ->
86+
- new TickThread(runnable, "WorldTickThread[" + threadCount.getAndIncrement() + "]")
87+
- );
88+
- previousPoolSize = pool;
89+
- worldThreadHashMap.clear();
90+
- }
91+
-
92+
Set<Future<?>> futures = new HashSet<>();
93+
for (ServerLevel serverLevel : serverLevels) {
94+
Future<?> future = executorService.submit(serverLevel.worldThread);

patches/server/0023-fix-11.patch

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: bea4dev <bea0224@outlook.jp>
3+
Date: Mon, 13 Jan 2025 05:39:14 +0900
4+
Subject: [PATCH] fix #11
5+
6+
7+
diff --git a/src/main/java/world/chiyogami/thread/WorldThread.java b/src/main/java/world/chiyogami/thread/WorldThread.java
8+
index 9517d26c465f25f68d33355e96cd7f1f73ae3eed..6ff13833c811b392194e8450b1b2f84562fc45ef 100644
9+
--- a/src/main/java/world/chiyogami/thread/WorldThread.java
10+
+++ b/src/main/java/world/chiyogami/thread/WorldThread.java
11+
@@ -178,38 +178,42 @@ public class WorldThread implements Runnable {
12+
}
13+
14+
ChiyogamiLogger.info("Try wait " + level.getWorld().getName() + " -> " + targetWorldThread.level.getWorld().getName());
15+
-
16+
- try {
17+
- TASK_SCHEDULING_LOCK.lock();
18+
- targetWorldThread.LOCK.lock();
19+
-
20+
- //Checks to see if threads waiting to exit are not recursively waiting for themselves.
21+
- WorldThread waitForThread = targetWorldThread;
22+
- do {
23+
- waitForThread = waitForThread.waitFor;
24+
- } while (waitForThread != null && waitForThread != this);
25+
-
26+
- if (waitForThread == null) {
27+
- if (targetWorldThread.isProcessingWorldTick) {
28+
- if (this.safeLockCount.get() != 0) {
29+
- throw new IllegalStateException("""
30+
- The current thread has already acquired a lock with WorldThreadSafeLock.
31+
- In this state, it cannot safely wait for another world's task completion.
32+
- This operation cannot be performed because it may cause a deadlock.""");
33+
+
34+
+ if (level != targetWorldThread.level) {
35+
+ try {
36+
+ TASK_SCHEDULING_LOCK.lock();
37+
+ targetWorldThread.LOCK.lock();
38+
+
39+
+ //Checks to see if threads waiting to exit are not recursively waiting for themselves.
40+
+ WorldThread waitForThread = targetWorldThread;
41+
+ do {
42+
+ waitForThread = waitForThread.waitFor;
43+
+ } while (waitForThread != null && waitForThread != this);
44+
+
45+
+ if (waitForThread == null) {
46+
+ if (targetWorldThread.isProcessingWorldTick) {
47+
+ if (this.safeLockCount.get() != 0) {
48+
+ throw new IllegalStateException("""
49+
+ The current thread has already acquired a lock with WorldThreadSafeLock.
50+
+ In this state, it cannot safely wait for another world's task completion.
51+
+ This operation cannot be performed because it may cause a deadlock.""");
52+
+ }
53+
+
54+
+ ChiyogamiLogger.info("Wait for " + level.getWorld().getName() + " -> " + targetWorldThread.level.getWorld().getName());
55+
+ targetWorldThread.worldTasks.add(worldTask);
56+
+ this.waitFor = targetWorldThread;
57+
+ } else {
58+
+ worldTask.complete();
59+
}
60+
-
61+
- ChiyogamiLogger.info("Wait for " + level.getWorld().getName() + " -> " + targetWorldThread.level.getWorld().getName());
62+
- targetWorldThread.worldTasks.add(worldTask);
63+
- this.waitFor = targetWorldThread;
64+
} else {
65+
worldTask.complete();
66+
}
67+
- } else {
68+
- worldTask.complete();
69+
+ } finally {
70+
+ targetWorldThread.LOCK.unlock();
71+
+ TASK_SCHEDULING_LOCK.unlock();
72+
}
73+
- } finally {
74+
- targetWorldThread.LOCK.unlock();
75+
- TASK_SCHEDULING_LOCK.unlock();
76+
+ } else {
77+
+ worldTask.complete();
78+
}
79+
80+
try {

0 commit comments

Comments
 (0)