From dd6aed273d53cabe58c56a6ba9078b424fee22a2 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 11 Feb 2026 07:45:42 -0600 Subject: [PATCH] Hopefully fix a rare concurrency issue in buffer Builder --- .../bufferBuilding/ColumnRenderBufferBuilder.java | 6 ++++++ .../render/columnViews/ColumnRenderView.java | 10 +++++++++- .../core/render/QuadTree/LodRenderSection.java | 6 ++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java index c762b4c45..a54116209 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java @@ -163,6 +163,12 @@ public class ColumnRenderBufferBuilder // get adjacent render data columns // //==================================// + // clear the old data so we can handle if one of the adjacent columns is missing/empty + adjColumnViews[EDhDirection.NORTH.compassIndex].clear(); + adjColumnViews[EDhDirection.SOUTH.compassIndex].clear(); + adjColumnViews[EDhDirection.EAST.compassIndex].clear(); + adjColumnViews[EDhDirection.WEST.compassIndex].clear(); + for (EDhDirection direction : EDhDirection.CARDINAL_COMPASS) { try diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/columnViews/ColumnRenderView.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/columnViews/ColumnRenderView.java index 749d410d5..47760bed2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/columnViews/ColumnRenderView.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/columnViews/ColumnRenderView.java @@ -111,6 +111,14 @@ public final class ColumnRenderView implements AutoCloseable } } + public void clear() + { + this.data = null; + this.size = 0; + this.offset = 0; + this.maxVerticalSliceCount = 0; + } + //endregion @@ -131,7 +139,7 @@ public final class ColumnRenderView implements AutoCloseable // we can fairly confidently say this is a concurrent exception over an actual // index out of bounds, since we're generally iterating over the whole // array any time we use this getter. - throw new ConcurrentModificationException("Potential concurrent modification detected. Make sure the parent ColumnRenderSource isn't being closed before the ColumnArrayView processing is complete.", e); + throw new ConcurrentModificationException("Potential concurrent modification detected. Make sure the parent ColumnRenderSource isn't being closed before the ColumnRenderView processing is complete.", e); } } public void set(int index, long value) { this.data.set(index + this.offset, value); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java index 25bc7f570..8c98dc9ed 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java @@ -325,9 +325,11 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable { if (!this.bufferUploadFutureRef.compareAndSet(future, null) // if the old future is canceled then the future ref will be different and that's expected - && !future.isCancelled()) + && !future.isCancelled() + // if the old future is already done, then we don't care about the ref being swapped + && !future.isDone()) { - LOGGER.error("Buffer upload future ref changed for pos: ["+DhSectionPos.toString(this.pos)+"]."); + LOGGER.warn("Buffer upload future ref changed for pos: ["+DhSectionPos.toString(this.pos)+"]."); } return null;