diff --git a/crates/script/src/socket.rs b/crates/script/src/socket.rs index 6b2976dc1..dc815a2d6 100644 --- a/crates/script/src/socket.rs +++ b/crates/script/src/socket.rs @@ -394,19 +394,33 @@ mod tests { /// Fill bounded socket buffers nonblocking, rather than assuming a 64 MiB write stalls. /// In particular, Windows may accept that entire write with its default send buffering. + /// Writes must stay blocked for [`SETTLED`] before the buffers count as full: on macOS the + /// accepted stream does not keep the listener's 4 KiB receive buffer (it gets about 114 KiB), + /// so the first `WouldBlock` only means the 4 KiB send buffer is full, and the send buffer then + /// drains into the peer's larger receive buffer. fn backpressure(id: u32) { + const SETTLED: Duration = Duration::from_millis(200); let mut stream = super::imp::test_stream(id); socket2::SockRef::from(&stream).set_send_buffer_size(4096).unwrap(); stream.set_nonblocking(true).unwrap(); let start = Instant::now(); let chunk = [b'x'; 4096]; let mut sent = 0; + let mut blocked_since = None; loop { assert!(sent < 16 * 1024 * 1024 && start.elapsed() < Duration::from_secs(5), "could not establish backpressure"); match stream.write(&chunk) { Ok(0) => panic!("peer closed while establishing backpressure"), - Ok(n) => sent += n, - Err(e) if e.kind() == ErrorKind::WouldBlock => break, + Ok(n) => { + sent += n; + blocked_since = None; + } + Err(e) if e.kind() == ErrorKind::WouldBlock => { + if blocked_since.get_or_insert_with(Instant::now).elapsed() >= SETTLED { + break; + } + std::thread::sleep(Duration::from_millis(5)); + } Err(e) if e.kind() == ErrorKind::Interrupted => continue, Err(e) => panic!("establishing backpressure: {e}"), }