aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
diff options
context:
space:
mode:
authorJason Mitchell <mitchej@gmail.com>2021-01-18 13:33:49 -0800
committerJason Mitchell <mitchej@gmail.com>2021-01-18 13:33:49 -0800
commitf3a6e82f96c2d39b6f0b1066bb2c431addfcbb7d (patch)
tree7eefa785c357812ce813d5d0e797a38d8d2aba4c /src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
parent00cfe596dd49c20398dcdeea776f04a02573cc43 (diff)
downloadGT5-Unofficial-f3a6e82f96c2d39b6f0b1066bb2c431addfcbb7d.tar.gz
GT5-Unofficial-f3a6e82f96c2d39b6f0b1066bb2c431addfcbb7d.tar.bz2
GT5-Unofficial-f3a6e82f96c2d39b6f0b1066bb2c431addfcbb7d.zip
Do some locking around getTileEntity to avoid CMEs on the main thread
Diffstat (limited to 'src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java')
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
index 8f7a84e2cb..494b21de1f 100644
--- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
@@ -1,5 +1,8 @@
package gregtech.api.threads;
+
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.common.gameevent.TickEvent;
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
@@ -15,6 +18,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
public class GT_Runnable_MachineBlockUpdate implements Runnable {
// used by runner thread
@@ -23,6 +27,9 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
private final Set<ChunkCoordinates> visited = new HashSet<>(80);
private final Queue<ChunkCoordinates> tQueue = new LinkedList<>();
+ // Locking
+ private static ReentrantLock lock = new ReentrantLock();
+
// Threading
private static final ThreadFactory THREAD_FACTORY = r -> {
Thread thread = new Thread(r);
@@ -40,6 +47,15 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
}
+ @SubscribeEvent
+ public void onServerTick(TickEvent.ServerTickEvent aEvent) {
+ if (aEvent.phase == TickEvent.Phase.START) {
+ lock.lock();
+ } else {
+ lock.unlock();
+ }
+ }
+
public static boolean isEnabled() {
return isEnabled;
}
@@ -101,8 +117,13 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
try {
while (!tQueue.isEmpty()) {
final ChunkCoordinates aCoords = tQueue.poll();
+
+ // This might load a chunk... which might load a TileEntity... which might get added to `loadedTileEntityList`... which might be in the process
+ // of being iterated over during `UpdateEntities()`... which might cause a ConcurrentModificationException. So, lock that shit.
+ lock.lock();
TileEntity tTileEntity = world.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
-
+ lock.unlock();
+
// See if the block itself needs an update
if (tTileEntity instanceof IMachineBlockUpdateable)
((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate();