From 1156eb8fe9475608d956b1ea0fdeb27efa61ad9c Mon Sep 17 00:00:00 2001 From: Cyd Date: Sat, 18 Jul 2026 00:11:26 -0500 Subject: [PATCH] Mash tool: dispose transport before awaiting the link on shutdown On a wedged (fully silent) board the receive loop sits in a pending net48 serial read that ignores cancellation; awaiting the link before closing the port hangs the tool at run end and loses the summary - exactly what happened on the first real baseline run (the board wedged at 0.62s and stayed dead, so no byte ever completed the read). Close the port first (same order RioCoordinator.Teardown uses); applies to both monitor and --mash modes. Selftest unaffected (its fake transport honors cancellation, which is why it never caught this). Co-Authored-By: Claude Fable 5 --- tools/RioSerialMonitor/MashTest.cs | 6 +++++- tools/RioSerialMonitor/Program.cs | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/RioSerialMonitor/MashTest.cs b/tools/RioSerialMonitor/MashTest.cs index 1f10739..7c66baa 100644 --- a/tools/RioSerialMonitor/MashTest.cs +++ b/tools/RioSerialMonitor/MashTest.cs @@ -281,9 +281,13 @@ internal static class MashTest // --- counters AFTER ------------------------------------------------------ Dictionary after = await SnapshotStatusAsync(); + // Dispose the transport BEFORE awaiting the link: on a wedged (silent) + // board the receive loop sits in a pending serial read that ignores + // cancellation — closing the port is what unblocks it. Awaiting first + // hangs forever and eats the summary (seen on the baseline chip run). cts.Cancel(); - try { await run; } catch { /* shutdown */ } transport.Dispose(); + try { await run; } catch { /* shutdown */ } // --- summary (fixed layout for diffing runs) ------------------------------ double mins = Math.Max(sw.Elapsed.TotalMinutes, 0.001); diff --git a/tools/RioSerialMonitor/Program.cs b/tools/RioSerialMonitor/Program.cs index c3f8298..b72acd7 100644 --- a/tools/RioSerialMonitor/Program.cs +++ b/tools/RioSerialMonitor/Program.cs @@ -148,9 +148,11 @@ Log(">>> NOW: press the MFD buttons, press keypad keys, and move the axis <<<"); Log(">>> a pressed button should light up <<<"); await Task.Delay(TimeSpan.FromSeconds(seconds)); +// Transport first: a silent board leaves the receive loop in a pending read +// that only the port close unblocks (net48 ReadAsync ignores cancellation). cts.Cancel(); -try { await run; } catch { /* shutdown */ } transport.Dispose(); +try { await run; } catch { /* shutdown */ } Console.WriteLine(); Console.WriteLine("== summary ==");