Skip to content

v1.0.9

Choose a tag to compare

@github-actions github-actions released this 12 Jun 01:54
· 17 commits to main since this release

NeewerLux v1.0.9 Release Notes

Bug Fix

Animation Chain Revert — Thread Race Condition Fixed

Fixed: Chained animations (triggering Animation 2 while Animation 1 is playing) would fail to revert to the original pre-animation state, instead freezing on the final frame of the last animation. Single-shot animations reverted correctly.

Root cause: A time-of-check-time-of-use (TOCTOU) race between the dying animation thread and the main thread. When startAnimation() interrupted a running animation, it set a _animChainStop flag to tell the dying thread "don't revert." But stopAnimation() only waited for animationRunning = False — the dying thread set that flag before reaching the revert check. By the time the dying thread actually checked _animChainStop, the main thread had already cleared it, so the revert ran anyway, wiping preAnimationStates.

Fix: The dying thread now captures _animChainStop into a local variable (isChaining) before setting animationRunning = False. The revert decision is made from the local copy, which is immune to subsequent clearing by either the main thread or the new animation thread. The flag is only cleared at the start of the new animation thread, after the old thread has already captured its value.

Timeline of this fix:

  • v1.0.5: First attempt — wasRunning guard to skip re-capturing states (incomplete, dying thread still cleared them)
  • v1.0.6: Second attempt — _animChainStop flag (fix was lost during merge and never committed)
  • v1.0.8: Re-applied _animChainStop (still had the TOCTOU race)
  • v1.0.9: fix with local variable capture before animationRunning = False

Full Changelog: https://github.com/poizenjam/NeewerLux/blob/main/CHANGELOG.md
Repository: https://github.com/poizenjam/NeewerLux