Sodium

Sodium

44M Downloads

Sodium uses Thread.interrupt() to stop chunk workers

embeddedt opened this issue ยท 0 comments

commented

Bug Description

It appears that in the current version (0.5.1) Sodium makes use of the Java Thread.interrupt API to stop its chunk workers:

https://github.com/CaffeineMC/sodium-fabric/blob/21e4e6d2f09f8d6b8ae7e5a5fab4a13c1f8379ce/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/executor/ChunkBuilder.java#L89-L92

The issue is Java NIO immediately closes a file channel that is in use when a thread is interrupted, rather than simply returning early. This also seems to cause any subsequent accesses to fail. This is not noticeable in vanilla but can be reproduced with ModernFix dynamic resources since it causes models & blockstates to be loaded on the chunk worker threads. This has not been an issue with prior versions of Sodium.

Please consider switching to an alternative means of stopping the worker threads.

Reproduction Steps

  1. Install Sodium & ModernFix 5.6.1.
  2. Set mixin.perf.dynamic_resources=true in config/modernfix-mixins.properties.
  3. Launch the game and connect to mc.minehut.com, and accept the server resource pack.
  4. It may be necessary to relaunch the game a second time and repeat the connection to see the issue occur.

Log File

Relevant stack trace attached here.

[13:11:59] [Render thread/INFO]: Stopping worker threads
[13:11:59] [Chunk Render Task Executor #0/ERROR]: Couldn't load blockstate
java.nio.channels.ClosedByInterruptException: null
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:199) ~[?:?]
	at sun.nio.ch.FileChannelImpl.endBlocking(FileChannelImpl.java:171) ~[?:?]
	at sun.nio.ch.FileChannelImpl.readInternal(FileChannelImpl.java:844) ~[?:?]
	at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:824) ~[?:?]
	at jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1241) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1236) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem$Entry.readLocEXTT(ZipFileSystem.java:3208) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem$Entry.readExtra(ZipFileSystem.java:3147) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem$Entry.readCEN(ZipFileSystem.java:2824) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem$Entry.<init>(ZipFileSystem.java:2760) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem.getEntry(ZipFileSystem.java:1923) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystem.newInputStream(ZipFileSystem.java:859) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipPath.newInputStream(ZipPath.java:749) ~[jdk.zipfs:?]
	at jdk.nio.zipfs.ZipFileSystemProvider.newInputStream(ZipFileSystemProvider.java:261) ~[jdk.zipfs:?]
	at java.nio.file.Files.newInputStream(Files.java:160) ~[?:?]
	at net.minecraft.class_7367.method_45301(class_7367.java:13) ~[client-intermediary.jar:?]
	at net.minecraft.class_3298.method_14482(class_3298.java:46) ~[client-intermediary.jar:?]
	at net.minecraft.class_3298.method_43039(class_3298.java:50) ~[client-intermediary.jar:?]
	at net.minecraft.class_1092.md1a4c3c$modernfix$lambda$loadSingleBlockState$3$1(class_1092.java:1558) ~[client-intermediary.jar:?]
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[?:?]
	at java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720) ~[?:?]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[?:?]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[?:?]
	at net.minecraft.class_1092.loadSingleBlockState(class_1092.java:1563) ~[client-intermediary.jar:?]
	at net.minecraft.class_1092.md1a4c3c$modernfix$lambda$deferBlockStateLoad$1$3(class_1092.java:1536) ~[client-intermediary.jar:?]
	at org.embeddedt.modernfix.util.LambdaMap.get(LambdaMap.java:41) ~[modernfix-fabric-5.6.1+mc1.20.1.jar:?]
	at java.util.Map.getOrDefault(Map.java:671) ~[?:?]
	at net.minecraft.class_1088.method_4715(class_1088.java:305) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.handler$zki000$modernfix$getOrLoadModelDynamic(class_1088.java:1270) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.method_4726(class_1088.java) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.method_4727(class_1088.java:389) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.redirect$zki000$modernfix$addTopLevelFile(class_1088.java:1179) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.method_4716(class_1088.java:168) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088$class_7778.handler$zkg000$modernfix$obtainModel(class_1088.java:586) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088$class_7778.method_45872(class_1088.java) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088$class_7778.method_45873(class_1088.java:419) ~[client-intermediary.jar:?]
	at net.minecraft.class_1088.bakeDefault(class_1088.java:1322) ~[client-intermediary.jar:?]
	at org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider.get(DynamicBakedModelProvider.java:141) ~[modernfix-fabric-5.6.1+mc1.20.1.jar:?]
	at org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider.get(DynamicBakedModelProvider.java:29) ~[modernfix-fabric-5.6.1+mc1.20.1.jar:?]
	at java.util.Map.getOrDefault(Map.java:671) ~[?:?]
	at net.minecraft.class_1092.method_4742(class_1092.java:71) ~[client-intermediary.jar:?]
	at net.minecraft.class_773.method_3335(class_773.java:540) ~[client-intermediary.jar:?]
	at me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask.execute(ChunkBuilderMeshingTask.java:97) ~[sodium-fabric-mc1.20.1-0.5.1.jar:?]
	at me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask.execute(ChunkBuilderMeshingTask.java:39) ~[sodium-fabric-mc1.20.1-0.5.1.jar:?]
	at me.jellysquid.mods.sodium.client.render.chunk.compile.executor.ChunkJobTyped.execute(ChunkJobTyped.java:44) ~[sodium-fabric-mc1.20.1-0.5.1.jar:?]
	at me.jellysquid.mods.sodium.client.render.chunk.compile.executor.ChunkBuilder$WorkerRunnable.run(ChunkBuilder.java:195) ~[sodium-fabric-mc1.20.1-0.5.1.jar:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

Crash Report

I have provided a technical explanation of why the issue occurs above, and the stacktrace in the crash report is misleading, but I can attach if it is really needed.