fix(worker): StaWaitHelper regression tests + full-drain contract notes; consolidate wait P/Invoke

This commit is contained in:
Joseph Doherty
2026-08-15 17:17:10 -04:00
parent 896d81e286
commit 7c9add3d73
10 changed files with 466 additions and 66 deletions
@@ -100,6 +100,20 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
this.variantConverter = variantConverter ?? throw new ArgumentNullException(nameof(variantConverter));
this.statusProxyConverter = new MxStatusProxyConverter();
this.alarmCommandHandler = alarmCommandHandler;
// The no-op fallback is a TEST affordance only — never pass null on a
// real STA. The cache wait loops this pump step feeds
// (MxAccessValueCache.TryWaitForUpdate,
// MxAccessWriteCompletionCache.TryWaitForCompletion) block in
// StaWaitHelper.WaitForSignalOrMessages, whose contract is that the pump
// step drains the message queue to empty on every call: the wait wakes on
// input that is merely present, so a pump step that removes nothing makes
// every wait return instantly and turns the loop into a busy spin at 100%
// CPU until its deadline (deadline and reply shape still hold — it is a
// CPU fault, not a correctness one). It is harmless here only because the
// fakes that pass null pre-populate the caches and run on threads with no
// windows and no pending input, so there is never a message left behind
// for the wait to keep waking on.
this.pumpStep = pumpStep ?? (static () => { });
this.writeCompletionTimeout = writeCompletionTimeout ?? DefaultWriteCompletionTimeout;
}