Commit cdff719
Schedule writer.close on loop thread in Connection.close best-effort arm
connection.py:1441-1448 — Connection.close()'s finally block called
writer.close() directly on the calling thread while self._loop is
still running on a different thread (loop.stop is queued via
call_soon_threadsafe several lines later). The sibling
force_close_transport at line 1554-1555 already schedules the same
call via loop.call_soon_threadsafe(_safe_writer_close, writer)
precisely because StreamWriter.close() mutates transport state
(_remove_reader on the selector) and is not thread-safe per stdlib.
Asymmetric discipline within the same file. The current
contextlib.suppress(Exception) masked the symptoms of the race.
Switch to call_soon_threadsafe(_safe_writer_close) when the loop
is alive; fall back to the synchronous call only when the loop
is already closed / unavailable. FIFO ready-queue discipline with
the subsequent loop.stop queue ensures FIN goes out before
run_forever exits — exactly the pattern force_close_transport
already uses.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent d04837f commit cdff719
1 file changed
Lines changed: 21 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1442 | 1442 | | |
1443 | 1443 | | |
1444 | 1444 | | |
1445 | | - | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
1446 | 1466 | | |
1447 | 1467 | | |
1448 | 1468 | | |
| |||
0 commit comments