Skip to content

fix: cancel license lock waits on teardown and write the license atomically - #41

Merged
TobbenTM merged 1 commit into
mainfrom
tbilisi/license-file-lock-issues-fix
Oct 12, 2026
Merged

TobbenTM merged 1 commit into
mainfrom
tbilisi/license-file-lock-issues-fix

Conversation

@TobbenTM

Copy link
Copy Markdown
Member

Closing a plugin while another instance held the license lock for its online check used to block teardown until that check finished, because the wait sat in a blocking flock(). The lock is now taken without blocking and retried, and the new file_license_store::cancel_lock_waits() lets ActivationController stop a pending wait when it is destroyed; on Windows this also replaces _LK_LOCK, which gave up after about 10 seconds and left the waiting instance locked. store_local_license now writes a temporary file and renames it into place, so a reader without the lock can no longer catch a half-written license and delete it as corrupt; it keeps the file's permissions, follows a symlinked path, and writes in place for hard links or folders that take no new files. New store and controller tests cover each case (each failed before the fix), and the full suite passes on macOS; the Windows lock and rename paths are exercised only in CI.

…ically

Instances that share a license file take turns re-validating it under a file
lock, and a waiting instance blocked in flock() with no way out. Destroying the
ActivationController while another instance held the lock for its own network
check therefore held up the host until that check finished, which offline can
take until the request times out. The lock is now taken without blocking and
retried, file_license_store gains cancel_lock_waits(), and the controller calls
it on teardown alongside its transport cancels. On Windows this also replaces
_LK_LOCK, which gave up after about 10 seconds and left a waiting instance
locked for the session.

store_local_license truncated and rewrote the license in place, while readers
such as an instance loading at startup read it without the lock, and
load_local_license deletes a file it cannot parse. A reader that caught a write
half done deleted the license. The store now writes a temporary file beside the
license and renames it into place, keeping the file's permissions, following a
symlinked license path, and writing in place for a hard-linked file or where no
new file can be created.

Tested with new store tests (a concurrent reader during repeated writes,
cancelling a lock wait, permissions, symlinks, hard links, the in-place
fallback) and a controller test that tears down while another store holds the
lock. Each failed before the fix; the full suite passes on macOS.
@argos-ci

argos-ci Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Oct 12, 2026, 12:38 PM

@TobbenTM
TobbenTM merged commit afec538 into main Oct 12, 2026
17 checks passed
github-actions Bot pushed a commit that referenced this pull request Oct 12, 2026
## [4.9.2](v4.9.1...v4.9.2) (2026-10-12)

### Bug Fixes

* cancel license lock waits on teardown and write the license atomically ([#41](#41)) ([afec538](afec538))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 4.9.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant