Robustness: bounded ASIO close, native service self-update, rollback pinned (review Phase 3)
- AsioApartment gains a bounded Invoke; the close path uses it (8s cap - a healthy close is ~5ms). A driver that wedges inside Stop/Dispose can no longer hang a live driver-switch or the resume path: the caller logs the timeout and abandons the driver (old park semantics, reclaimed at process exit). Apartment test extended to pin the timeout path. - Service self-update is now NATIVE code: a detached copy of the NEW build runs --service-selfupdate (stop -> CopyProgramTo -> start, every step logged to the update log). The old PowerShell restart script silently died wherever Group Policy enforces execution policy (Bypass is ignored there), stranding the service on the old build. Verb wired through IsServiceInvocation + ServiceEntry; verb-gate test now pins all six verbs. - UpdateApplier SwapInNewFiles/RollBack made internal + pinned by a real-folder test: swap lands exactly the release's files (user files untouched), backup holds the originals, rollback restores BYTE-EXACT including deleting newly-created files - the contract that stops a failed update bricking an install. - RouterPortMapper: discovery callback now checks disposed under the gate, so an in-flight callback can't re-open the port map Dispose just removed. Gate 59/59. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -237,6 +237,10 @@ internal sealed class RouterPortMapper : IDisposable
|
||||
|
||||
private void OnDeviceFound(object? sender, DeviceEventArgs args)
|
||||
{
|
||||
// A discovery callback can already be in flight when Stop()/Dispose() unsubscribes. Without this
|
||||
// guard it would re-open the port map that Dispose just removed, leaving the router forwarding to
|
||||
// us until the lease expires. Narrow race, cheap check (review sweep).
|
||||
lock (gate) { if (disposed) return; }
|
||||
try
|
||||
{
|
||||
var found = args.Device;
|
||||
|
||||
Reference in New Issue
Block a user