From d2a5b1e607eb22d2750f82913465a556210ae1bb Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sat, 25 Oct 2025 18:57:40 +1000 Subject: [PATCH] Fix deadlock in servicemanager + use sodiums thread pool for our own use --- .../mixin/sodium/MixinChunkJobQueue.java | 37 +++++++++++++++++++ .../voxy/common/thread3/ServiceManager.java | 5 ++- src/main/resources/client.voxy.mixins.json | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/cortex/voxy/client/mixin/sodium/MixinChunkJobQueue.java diff --git a/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinChunkJobQueue.java b/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinChunkJobQueue.java new file mode 100644 index 00000000..ddab925a --- /dev/null +++ b/src/main/java/me/cortex/voxy/client/mixin/sodium/MixinChunkJobQueue.java @@ -0,0 +1,37 @@ +package me.cortex.voxy.client.mixin.sodium; + +import me.cortex.voxy.client.compat.SemaphoreBlockImpersonator; +import me.cortex.voxy.common.thread3.MultiThreadPrioritySemaphore; +import me.cortex.voxy.commonImpl.VoxyCommon; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.concurrent.Semaphore; + +@Mixin(targets={"net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkJobQueue"},remap = false) +public class MixinChunkJobQueue { + @Unique private MultiThreadPrioritySemaphore.Block voxy$semaphoreBlock; + + @Redirect(method = "", at = @At(value = "NEW", target = "(I)Ljava/util/concurrent/Semaphore;")) + private Semaphore voxy$injectUnifiedPool(int permits) { + var instance = VoxyCommon.getInstance(); + if (instance != null) { + this.voxy$semaphoreBlock = instance.getThreadPool().groupSemaphore.createBlock(); + return new SemaphoreBlockImpersonator(this.voxy$semaphoreBlock); + } + return new Semaphore(permits); + } + + @Inject(method = "shutdown", at = @At("RETURN")) + private void voxy$injectAtShutdown(CallbackInfoReturnable ci) { + if (this.voxy$semaphoreBlock != null) { + this.voxy$semaphoreBlock.free(); + } + } +} diff --git a/src/main/java/me/cortex/voxy/common/thread3/ServiceManager.java b/src/main/java/me/cortex/voxy/common/thread3/ServiceManager.java index dac462c6..98872b52 100644 --- a/src/main/java/me/cortex/voxy/common/thread3/ServiceManager.java +++ b/src/main/java/me/cortex/voxy/common/thread3/ServiceManager.java @@ -60,7 +60,7 @@ public class ServiceManager { public boolean runAJob() {//Executes a single job on the current thread while (true) { - if (this.services.length == 0) return false; + if (this.services.length == 0 || this.totalJobs.get() == 0) return false; if (this.runAJob0()) return true; try { Thread.sleep(10); @@ -169,6 +169,9 @@ public class ServiceManager { } void remJobs(int remaining) { + //TODO:FIXME: THIS NEEDS TO BUBBLE UP TO THE jobRelease thing + // AFAK! if this is zero inside the runAJob loop, it must return + if (this.totalJobs.addAndGet(-remaining)<0) { throw new IllegalStateException("total jobs <0"); } diff --git a/src/main/resources/client.voxy.mixins.json b/src/main/resources/client.voxy.mixins.json index c1bf8506..389263df 100644 --- a/src/main/resources/client.voxy.mixins.json +++ b/src/main/resources/client.voxy.mixins.json @@ -29,6 +29,7 @@ "minecraft.MixinWorldRenderer", "nvidium.MixinRenderPipeline", "sodium.AccessorChunkTracker", + "sodium.MixinChunkJobQueue", "sodium.MixinDefaultChunkRenderer", "sodium.MixinRenderSectionManager", "sodium.MixinSodiumOptionsGUI"