Windows lock release before contention probing
Windows 锁在竞争探测前释放
Windows exclusive file creation can report `EPERM` while another writer owns the lock. The holder can remove the lock before the contender's `lstat`, so absence at that later observation does not prove the create failed for a persistent permission restriction. The profile module-fallback contention test exposed this race.
English
Problem
Windows exclusive file creation can report EPERM while another writer owns the lock. The holder can remove the lock before the contender's lstat, so absence at that later observation does not prove the create failed for a persistent permission restriction. The profile module-fallback contention test exposed this race.
Decision
withFileLock permits one unconfirmed EPERM retry per Windows acquisition, using the existing backoff and deadline. Confirmed contention still waits normally. A second unconfirmed permission failure is rethrown, and the protected operation runs only after exclusive creation succeeds.
Alternatives considered
Retrying every permission error until timeout would obscure persistent permission failures. Requiring the lock to exist during the later probe rejects a valid release race. Delaying the test's holder release changes timing without repairing the writer protocol.
Consequences
A persistent Windows permission failure can incur one backoff before failing. POSIX behavior is unchanged. The atomic-write tests force release before the probe and verify both successful acquisition and persistent permission rejection; the profile tests exercise real competing writers. Existing credential-registration notes retain ownership of write serialization and are not superseded by this acquisition rule.
中文
问题
Windows 独占创建文件时,若另一写入方持有锁,可能报告 EPERM。持锁方可能在竞争者执行 lstat 前删除锁,因此之后观察到锁不存在,并不能证明创建失败源于持续的权限限制。profile 模块回退的竞争测试暴露了这一竞态。
决策
withFileLock 在每次 Windows 获取锁的过程中允许对无法确认锁存在的 EPERM 重试一次,沿用现有退避与截止时间。确认存在的竞争仍正常等待。第二次无法确认锁存在的权限失败会重新抛出,且只有独占创建成功后才会运行受保护操作。
考虑过的替代方案
对所有权限错误一直重试到超时会掩盖持续的权限失败。要求锁在之后探测时仍存在会拒绝合法的释放竞态。延迟测试中持锁方的释放只改变时序,无法修复写入协议。
后果
Windows 持续的权限失败可能在一次退避后才报告。POSIX 行为不变。atomic-write 测试强制在探测前释放锁,并验证成功获取锁和持续权限失败;profile 测试覆盖真实的竞争写入方。现有凭据注册笔记仍负责写入串行化决策,不会被此获取锁规则取代。