Fix crash on exit due to no shutdown for cutAndExpend thread

Also tweeked the values of vertQual on larger blocks to better support floating
islands.
This commit is contained in:
tom lee
2022-01-30 15:30:09 +08:00
parent 4bcb6c0acd
commit 99ca5f6bc6
5 changed files with 52 additions and 38 deletions
@@ -133,41 +133,27 @@ public class EventApi
// Note: using isCurrentlyOnSinglePlayerServer as often API call unload event AFTER setting MC to not be in a singlePlayerServer
if (isCurrentlyOnSinglePlayerServer && world.getWorldType() == WorldType.ClientWorld) return;
// the player just unloaded a world/dimension
checkIfDisconnectedFromServer();
}
private void checkIfDisconnectedFromServer()
{
{
// the player just left the server
// TODO should "resetMod()" be called here? -James
// if this isn't done unfinished tasks may be left in the queue
// preventing new LodChunks form being generated
ApiShared.isShuttingDown = true;
// TODO Check why world gen is sometimes stuck and timeout
LodWorldGenerator.INSTANCE.restartExecutorService();
LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0);
ApiShared.lodWorld.deselectWorld(); // This force a save
// prevent issues related to the buffer builder
// breaking or retaining previous data when changing worlds.
ClientApi.renderer.destroyBuffers();
ClientApi.renderer.requestCleanup();
GLProxy.ensureAllGLJobCompleted();
recalculateWidths = true;
// TODO: Check if after the refactoring, is this still needed
ClientApi.renderer = new LodRenderer(ApiShared.lodBufferBuilderFactory);
ClientApi.INSTANCE.rendererDisabledBecauseOfExceptions = false;
// make sure the nulled objects are freed.
// (this prevents an out of memory error when
// changing worlds)
System.gc();
}
// TODO should "resetMod()" be called here? -James
// if this isn't done unfinished tasks may be left in the queue
// preventing new LodChunks form being generated
ApiShared.isShuttingDown = true;
// TODO Better report on when world gen is stuck and timeout
LodWorldGenerator.INSTANCE.restartExecutorService();
ApiShared.lodWorld.deselectWorld(); // This force a save and shutdown lodDim properly
// prevent issues related to the buffer builder
// breaking or retaining previous data when changing worlds.
ClientApi.renderer.destroyBuffers();
ClientApi.renderer.requestCleanup();
GLProxy.ensureAllGLJobCompleted();
recalculateWidths = true;
// TODO: Check if after the refactoring, is this still needed
ClientApi.renderer = new LodRenderer(ApiShared.lodBufferBuilderFactory);
ClientApi.INSTANCE.rendererDisabledBecauseOfExceptions = false;
}
public void blockChangeEvent(IChunkWrapper chunk, IDimensionTypeWrapper dimType)
@@ -75,7 +75,7 @@ public class LodWorldGenerator
* to limit how many chunks are queued at once. To prevent chunks from being
* generated for a long time in an area the player is no longer in.
*/
public final AtomicInteger numberOfChunksWaitingToGenerate = new AtomicInteger(0);
public AtomicInteger numberOfChunksWaitingToGenerate = new AtomicInteger(0);
public final Set<AbstractChunkPosWrapper> positionsWaitingToBeGenerated = new HashSet<>();
@@ -385,6 +385,8 @@ public class LodWorldGenerator
new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
}
}
// Doing this instead of setting it to 0 because even if shutdown fail, it won't cause the int to underflow below 0 afterwards
numberOfChunksWaitingToGenerate = new AtomicInteger(0);
}
}
@@ -34,12 +34,12 @@ public enum VerticalQuality
),
MEDIUM(
new int[] { 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1 },
new int[] { 8, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1 },
8
),
HIGH(
new int[] { 16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1 },
new int[] { 16, 8, 4, 2, 2, 2, 2, 1, 1, 1, 1 },
16
);
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
@@ -780,4 +781,16 @@ public class LodDimension
}
return stringBuilder.toString();
}
public void shutdown() {
cutAndExpandThread.shutdown();
try {
boolean worked = cutAndExpandThread.awaitTermination(5, TimeUnit.SECONDS);
if (!worked)
ClientApi.LOGGER.error("Cut And Expend threads timed out! May cause crash on game exit due to cleanup failure.");
} catch (InterruptedException e) {
ClientApi.LOGGER.error("Cut And Expend threads shutdown is interrupted! May cause crash on game exit due to cleanup failure: ", e);
}
}
}
@@ -149,6 +149,19 @@ public class LodWorld
}
//FIXME: This should block until file is saved.
}
/**
* Requests all dimensions to shutdown
*/
public void shutdownAllDimensions()
{
if (lodDimensions == null)
return;
// TODO: Add parallel shutdowns.
for (IDimensionTypeWrapper key : lodDimensions.keySet()) {
lodDimensions.get(key).shutdown();
}
}
public boolean getIsWorldNotLoaded()