@@ -378,18 +378,27 @@ impl<
378378 // 16 is the lowest I've seen mention of, and I've seen 1024 more commonly.
379379 const UIO_MAXIOV : usize = 256 ;
380380
381- let buffers: Vec < IoSlice > = self
382- . send_buffer
383- . iter ( )
384- . take ( UIO_MAXIOV )
385- . map ( |v| IoSlice :: new ( v. chunk ( ) ) )
386- . collect ( ) ;
381+ // Use chunks_vectored rather than chunk() to correctly handle
382+ // Buf implementations that aren't backed by a single contiguous slice.
383+ let mut stack_buffers = [ IoSlice :: new ( & [ ] ) ; UIO_MAXIOV ] ;
384+ let mut filled = 0 ;
385+ for buf in self . send_buffer . iter ( ) {
386+ if UIO_MAXIOV <= filled {
387+ break ;
388+ }
389+ let n = buf. chunks_vectored ( & mut stack_buffers[ filled..] ) ;
390+ if n == 0 {
391+ break ;
392+ }
393+ filled += n;
394+ }
395+ let buffers = & stack_buffers[ ..filled] ;
387396
388397 #[ cfg( feature = "tracing" ) ]
389398 let span = tracing:: span!( tracing:: Level :: INFO , "writing" , buffers = buffers. len( ) ) ;
390399 #[ cfg( feature = "tracing" ) ]
391400 let span_guard = span. enter ( ) ;
392- let poll = pin ! ( & mut self . stream) . poll_write_vectored ( context, & buffers) ;
401+ let poll = pin ! ( & mut self . stream) . poll_write_vectored ( context, buffers) ;
393402 #[ cfg( feature = "tracing" ) ]
394403 drop ( span_guard) ;
395404 match poll {
@@ -423,7 +432,7 @@ impl<
423432 "error while writing to tcp stream: {err:?}, buffers: {}, {}b: {:?}" ,
424433 buffers. len( ) ,
425434 buffers. iter( ) . map( |b| b. len( ) ) . sum:: <usize >( ) ,
426- buffers. into_iter ( ) . map( |b| b. len( ) ) . collect:: <Vec <_>>( )
435+ buffers. iter ( ) . map( |b| b. len( ) ) . collect:: <Vec <_>>( )
427436 ) ;
428437 Err ( err)
429438 }
0 commit comments