-
v0.4.2+26.1.2
StableSome checks failedBuild / build (push) Has been cancelledreleased this
2026-07-02 00:41:32 +00:00 | 12 commits to main since this releaseFixed: PasteOperation semaphore deadlock (Folia region self-deadlock)
Completes the v0.4.1 fix, which only hopped the pass-1 dispatch loop off the region tick thread.
Root cause. The pass-2 loop (
pass1All.thenCompose(...)) and the deferred-physics sweep loop (pass2All.thenCompose(...)) used a plain (non-async)thenCompose. That runs its body on the thread that completed the upstream future; completed bydone.complete(null)insideFoliaCompat.runOnRegion, i.e. a Folia region tick thread. Those loops then called the blockingacquireSlot()on that region thread. When the same region still had more pending chunk tasks than freeCHUNK_THROTTLEpermits, the region parked inSemaphore.acquire()waiting for permits only it could release → self-deadlock. Watchdog loggedTick region … has not respondedindefinitely without crashing; cumulative across Overworld + Nether. On creaclone a region was stuck ~116 h before a manual restart (issue #1); stacks atPasteOperation.java:293(pass 2) and:345(sweep).Fix.
- Both continuation loops now run via
thenComposeAsync(..., offRegionExecutor)(Folia async pool / Paper async worker) → everyacquireSlot()runs off-region; a blocked dispatch thread can no longer park a region. acquireSlot()now usestryAcquire(60 s)and reports whether a permit was taken; a timeout dispatches the chunk unthrottled + logs instead of blocking forever. ThereleasedOnceguard is seeded so an untaken permit is never over-released.
No config/schema change vs 0.4.1; in-place drop-in. Normal-load behaviour (32 in-flight chunk-task throttle) unchanged.
Fixes #1.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Both continuation loops now run via