Commit 37976fc
Race initialize request against processing loop for timing-independent fix
When a server process exits immediately, the message processing loop can
complete its pending-request sweep before SendRequestAsync registers the
initialize TCS. The existing flag+check pattern handles most interleavings
but ConcurrentDictionary iteration is non-atomic, leaving edge cases in
Debug builds with wider timing windows.
Use Task.WhenAny to race the initialize request against the processing
task. If the processing loop exits first (EOF on stdout), we detect it
immediately and throw IOException instead of hanging indefinitely.
The flag-based defense in McpSessionHandler.SendRequestAsync is kept as
defense-in-depth for post-initialization requests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 8d8df28 commit 37976fc
1 file changed
Lines changed: 18 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
533 | 533 | | |
534 | 534 | | |
535 | 535 | | |
536 | | - | |
| 536 | + | |
537 | 537 | | |
538 | 538 | | |
539 | 539 | | |
| |||
543 | 543 | | |
544 | 544 | | |
545 | 545 | | |
546 | | - | |
| 546 | + | |
547 | 547 | | |
548 | 548 | | |
549 | 549 | | |
| |||
553 | 553 | | |
554 | 554 | | |
555 | 555 | | |
556 | | - | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
557 | 572 | | |
558 | 573 | | |
559 | 574 | | |
| |||
0 commit comments