Fix null pointers when moving between multiverse levels

This commit is contained in:
James Seibel
2023-11-20 07:35:10 -06:00
parent 8af14ad3e7
commit 7e869105cb
8 changed files with 46 additions and 12 deletions
@@ -232,6 +232,11 @@ public class SharedApi
// lighting the chunk needs to be done on a separate thread to prevent lagging any of the event threads
ThreadPoolExecutor executor = ThreadPools.getLightPopulatorExecutor();
if (executor == null)
{
return;
}
executor.execute(() ->
{
LOGGER.trace(chunkWrapper.getChunkPos() + " " + executor.getActiveCount() + " / " + executor.getQueue().size() + " - " + executor.getCompletedTaskCount());
@@ -39,6 +39,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Used to populate the buffers in a {@link ColumnRenderSource} object.
@@ -66,6 +67,17 @@ public class ColumnRenderBufferBuilder
IDhClientLevel clientLevel, Reference<ColumnRenderBuffer> renderBufferRef,
ColumnRenderSource renderSource, ColumnRenderSource[] adjData)
{
ThreadPoolExecutor bufferBuilderExecutor = ThreadPools.getBufferBuilderExecutor();
ThreadPoolExecutor bufferUploaderExecutor = ThreadPools.getBufferUploaderExecutor();
if ((bufferBuilderExecutor == null || bufferBuilderExecutor.isTerminated()) ||
(bufferUploaderExecutor == null || bufferUploaderExecutor.isTerminated()))
{
// one or more of the thread pools has been shut down
CompletableFuture<ColumnRenderBuffer> future = new CompletableFuture<>();
future.cancel(true);
return future;
}
//LOGGER.info("RenderRegion startBuild @ "+renderSource.sectionPos);
return CompletableFuture.supplyAsync(() ->
{
@@ -101,7 +113,7 @@ public class ColumnRenderBufferBuilder
LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3);
throw e3;
}
}, ThreadPools.getBufferBuilderExecutor())
}, bufferBuilderExecutor)
.thenApplyAsync((quadBuilder) ->
{
try
@@ -136,7 +148,7 @@ public class ColumnRenderBufferBuilder
LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3);
throw e3;
}
}, ThreadPools.getBufferUploaderExecutor())
}, bufferUploaderExecutor)
.handle((columnRenderBuffer, ex) ->
{
//LOGGER.info("RenderRegion endBuild @ {}", renderSource.sectionPos);
@@ -102,6 +102,12 @@ public class ChunkToLodBuilder implements AutoCloseable
return;
}
ThreadPoolExecutor lodBuilderExecutor = ThreadPools.getChunkToLodBuilderExecutor();
if (lodBuilderExecutor == null)
{
return;
}
for (int i = 0; i < threadCount; i++)
{
@@ -116,7 +122,7 @@ public class ChunkToLodBuilder implements AutoCloseable
{
this.runningCount.decrementAndGet();
}
}, ThreadPools.getChunkToLodBuilderExecutor());
}, lodBuilderExecutor);
}
}
private void tickThreadTask()
@@ -247,7 +247,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
ThreadPoolExecutor executor = ThreadPools.getFileHandlerExecutor();
if (!executor.isTerminated())
if (executor != null && !executor.isTerminated())
{
// load the data source
@@ -344,7 +344,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
else
{
ThreadPoolExecutor executor = ThreadPools.getFileHandlerExecutor();
if (!executor.isTerminated())
if (executor != null && !executor.isTerminated())
{
// wait for the update to finish before returning the data source
@@ -104,7 +104,7 @@ public class RenderSourceFileHandler implements IRenderSourceProvider
{
// don't continue if the handler has been shut down
ThreadPoolExecutor executor = ThreadPools.getFileHandlerExecutor();
if (executor.isTerminated())
if (executor != null && executor.isTerminated())
{
return CompletableFuture.completedFuture(null);
}
@@ -266,11 +266,14 @@ public class RenderSourceFileHandler implements IRenderSourceProvider
private String[] f3Log()
{
ThreadPoolExecutor executor = ThreadPools.getFileHandlerExecutor();
String queueSize = executor != null ? executor.getQueue().size()+"" : "-";
String completedTaskSize = executor != null ? executor.getCompletedTaskCount()+"" : "-";
ArrayList<String> lines = new ArrayList<>();
lines.add("Render Source File Handler [" + this.clientLevel.getClientLevelWrapper().getDimensionType().getDimensionName() + "]");
lines.add(" Loaded files: " + this.loadedMetaFileBySectionPos.size());
lines.add(" Thread pool tasks: " + executor.getQueue().size() + " (completed: " + executor.getCompletedTaskCount() + ")");
lines.add(" Thread pool tasks: " + queueSize + " (completed: " + completedTaskSize + ")");
int totalFutures = this.taskTracker.size();
EnumMap<ETaskType, Integer> tasksOutstanding = new EnumMap<>(ETaskType.class);
@@ -518,7 +518,8 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender
try
{
int waitTimeInSeconds = 3;
if (!ThreadPools.getWorldGenExecutor().awaitTermination(waitTimeInSeconds, TimeUnit.SECONDS))
ThreadPoolExecutor executor = ThreadPools.getWorldGenExecutor();
if (executor != null && !executor.awaitTermination(waitTimeInSeconds, TimeUnit.SECONDS))
{
LOGGER.warn("World generator thread pool shutdown didn't complete after [" + waitTimeInSeconds + "] seconds. Some world generator requests may still be running.");
}
@@ -324,10 +324,10 @@ public class LodRenderSection implements IDebugRenderable
if (showRenderSectionStatus && this.pos.getDetailLevel() == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL)
{
DebugRenderer.makeParticle(
new DebugRenderer.BoxParticle(
new DebugRenderer.Box(this.pos, 32f, 64f, 0.2f, Color.yellow),
0.5, 16f
)
new DebugRenderer.BoxParticle(
new DebugRenderer.Box(this.pos, 32f, 64f, 0.2f, Color.yellow),
0.5, 16f
)
);
}
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.util.threading;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
import com.seibel.distanthorizons.core.util.ThreadUtil;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
@@ -42,13 +43,16 @@ public class ThreadPools
public static final DhThreadFactory FILE_HANDLER_THREAD_FACTORY = new DhThreadFactory("File Handler", Thread.MIN_PRIORITY);
private static ConfigThreadPool fileHandlerThreadPool;
@Nullable
public static ThreadPoolExecutor getFileHandlerExecutor() { return fileHandlerThreadPool.executor; }
public static final DhThreadFactory WORLD_GEN_THREAD_FACTORY = new DhThreadFactory("World Gen", Thread.MIN_PRIORITY);
private static ConfigThreadPool worldGenThreadPool;
@Nullable
public static ThreadPoolExecutor getWorldGenExecutor() { return worldGenThreadPool.executor; }
private static ThreadPoolExecutor bufferUploaderThreadPool;
@Nullable
public static ThreadPoolExecutor getBufferUploaderExecutor() { return bufferUploaderThreadPool; }
@@ -63,14 +67,17 @@ public class ThreadPools
public static final DhThreadFactory LIGHT_POPULATOR_THREAD_FACTORY = new DhThreadFactory("LOD Builder - Light Populator", Thread.MIN_PRIORITY);
private static ConfigThreadPool lightPopulatorThreadPool;
@Nullable
public static ThreadPoolExecutor getLightPopulatorExecutor() { return lightPopulatorThreadPool.executor; }
public static final DhThreadFactory CHUNK_TO_LOD_BUILDER_THREAD_FACTORY = new DhThreadFactory("LOD Builder - Chunk to Lod Builder", Thread.MIN_PRIORITY);
private static ConfigThreadPool chunkToLodBuilderThreadPool;
@Nullable
public static ThreadPoolExecutor getChunkToLodBuilderExecutor() { return chunkToLodBuilderThreadPool.executor; }
public static final DhThreadFactory BUFFER_BUILDER_THREAD_FACTORY = new DhThreadFactory("LOD Builder - Buffer Builder", Thread.MIN_PRIORITY);
private static ConfigThreadPool bufferBuilderThreadPool;
@Nullable
public static ThreadPoolExecutor getBufferBuilderExecutor() { return bufferBuilderThreadPool.executor; }