Commit 3375435
authored
Fix SctpDataSender lost-wakeup race: move _senderMre.Reset() to top of DoSend loop (#1560)
Root cause: _senderMre.Reset() was called AFTER the send work and BEFORE
_senderMre.Wait(burstPeriod). If a SACK arrived between the last chunk
sent and the Reset, its _senderMre.Set() signal was wiped by the Reset()
and the sender thread then blocked for the full BURST_PERIOD_MILLISECONDS
(50 ms default) before noticing more cwnd was available. On localhost
loopback where SACKs round-trip in microseconds the race window was hit
almost every burst, capping actual throughput at the theoretical
MAX_BURST * MTU / BURST_PERIOD steady-state (~104 KB/s for MTU=1300 +
50 ms period) rather than the much higher rate the link could sustain.
Fix: Reset at the START of each iteration so any Set() fired during the
send work is preserved through to the next Wait(). Wait returns promptly
on the SACK signal, and throughput becomes bounded by MRE wake latency
(sub-millisecond) rather than the 50 ms burst period. RFC 4960 §7.2.2
defaults (MAX_BURST, BURST_PERIOD_MILLISECONDS) unchanged.
Includes a regression test, SctpDataSenderUnitTest.Throughput_FastSack
Wake_ExceedsBurstCeiling: sends 360 x 1400-byte chunks (504 KB total)
with synchronous SACK delivery on the same thread, asserts completion
in under 2 seconds. Pre-fix measurement: 5613 ms / 89.8 KB/s. Post-fix
on the same machine: 94 ms / 5.4 MB/s (60x speedup). Pre-fix test
fails at the 2000 ms threshold; post-fix passes with ~20x headroom.
No regressions on the existing SctpData* tests (53/55 pass, 2 pre-
existing CI skips unrelated to this change).
Diagnostic credit to Geordi (a crew AI agent on the LostBeard team)
who traced the throughput ceiling to SctpDataSender.cs line by line
before filing the handoff that prompted this investigation. Fix
authored by LostBeard with AI-assisted code review from Riker (another
crew AI agent) and a Rule-4b verify-before-you-speak step where the
test was run against an intentionally-reverted version of the fix to
prove the failure mode matches the measured ceiling before re-applying.1 parent f3f32f9 commit 3375435
2 files changed
Lines changed: 84 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
526 | 526 | | |
527 | 527 | | |
528 | 528 | | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
529 | 542 | | |
530 | 543 | | |
531 | 544 | | |
| |||
615 | 628 | | |
616 | 629 | | |
617 | 630 | | |
618 | | - | |
619 | | - | |
620 | 631 | | |
621 | 632 | | |
622 | 633 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
| 20 | + | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| |||
90 | 92 | | |
91 | 93 | | |
92 | 94 | | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
93 | 164 | | |
94 | 165 | | |
95 | 166 | | |
| |||
0 commit comments