Commit dac3d4e
committed
fix: prevent stack overflow in transport close with re-entrancy guard
When 15-25+ transports close simultaneously, close() -> onclose()
triggers the Protocol layer to call close() again recursively,
causing a stack overflow. The process stays alive but becomes
unresponsive.
Three problems in the original close():
1. No re-entrancy guard: onclose() can call back into close()
2. Iterating _streamMapping while cleanup callbacks delete from it
3. No error isolation: one failing cleanup prevents others
The fix:
- Adds _closing boolean guard to prevent recursive calls
- Snapshots stream values into an array and clears the map before
iterating, avoiding mutation-during-iteration
- Wraps each cleanup() in try/catch so one failure doesn't block
remaining stream cleanups
- Calls onclose() only after all cleanup is complete
Note: two prior PRs (#1700, #1705) attempted similar fixes but were
closed. This implementation combines the best elements of both:
the re-entrancy guard from #1700 and the snapshot-before-clear
pattern from #1705, with the addition of error isolation.
Closes #16991 parent cce3ac7 commit dac3d4e
1 file changed
+24
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
899 | 899 | | |
900 | 900 | | |
901 | 901 | | |
| 902 | + | |
| 903 | + | |
902 | 904 | | |
903 | | - | |
904 | | - | |
905 | | - | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
906 | 910 | | |
907 | | - | |
| 911 | + | |
908 | 912 | | |
909 | | - | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
910 | 917 | | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
911 | 930 | | |
912 | 931 | | |
913 | 932 | | |
| |||
0 commit comments