mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-22 03:32:39 -05:00
Every socket operation locked one global table and held it through the blocking write_all/flush, and streams had no write timeout (accepted ones were explicitly blocking). A peer that stopped reading kept the script blocked for good, and every other socket call, close included, waited behind it. - The table maps handles to Arc<Entry>, each with its own Mutex<Sock>. The table is locked only to look a socket up, add or remove one, never during network I/O, so one stalled socket doesn't hold up the others. - `write` sets a write timeout from the socket's `timeout` (10 s by default, as reads) and reports "write timed out … the other side isn't reading" instead of blocking. Failures to set the read or write timeout, or to make an accepted stream blocking, are reported instead of ignored. - `close` removes the socket and shuts its stream down through a second handle, so a call blocked on it fails at once. Tests (socket.rs, native only): a 64 MB write to a loopback peer that never reads fails with "timed out" after a 1 s timeout; while one socket is blocked writing, another answers at once, and closing the blocked one returns at once and ends its write. Both fail on main (the write never gives up; the second socket waits on the table lock). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>