@@ -328,19 +328,57 @@ impl<W: Write> Write for BufWriter<W> {
328328 }
329329
330330 fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
331- let total_len = bufs. iter ( ) . map ( |b| b. len ( ) ) . sum :: < usize > ( ) ;
332- if self . buf . len ( ) + total_len > self . buf . capacity ( ) {
333- self . flush_buf ( ) ?;
334- }
335- // FIXME: Why no len > capacity? Why not buffer len == capacity? #72919
336- if total_len >= self . buf . capacity ( ) {
337- self . panicked = true ;
338- let r = self . get_mut ( ) . write_vectored ( bufs) ;
339- self . panicked = false ;
340- r
331+ if self . get_ref ( ) . is_write_vectored ( ) {
332+ let total_len = bufs. iter ( ) . map ( |b| b. len ( ) ) . sum :: < usize > ( ) ;
333+ if self . buf . len ( ) + total_len > self . buf . capacity ( ) {
334+ self . flush_buf ( ) ?;
335+ }
336+ if total_len >= self . buf . capacity ( ) {
337+ self . panicked = true ;
338+ let r = self . get_mut ( ) . write_vectored ( bufs) ;
339+ self . panicked = false ;
340+ r
341+ } else {
342+ bufs. iter ( ) . for_each ( |b| self . buf . extend_from_slice ( b) ) ;
343+ Ok ( total_len)
344+ }
341345 } else {
342- bufs. iter ( ) . for_each ( |b| self . buf . extend_from_slice ( b) ) ;
343- Ok ( total_len)
346+ let mut total_written = 0 ;
347+ let mut iter = bufs. iter ( ) ;
348+ if let Some ( buf) = iter. by_ref ( ) . find ( |& buf| !buf. is_empty ( ) ) {
349+ // This is the first non-empty slice to write, so if it does
350+ // not fit in the buffer, we still get to flush and proceed.
351+ if self . buf . len ( ) + buf. len ( ) > self . buf . capacity ( ) {
352+ self . flush_buf ( ) ?;
353+ }
354+ if buf. len ( ) >= self . buf . capacity ( ) {
355+ // The slice is at least as large as the buffering capacity,
356+ // so it's better to write it directly, bypassing the buffer.
357+ self . panicked = true ;
358+ let r = self . get_mut ( ) . write ( buf) ;
359+ self . panicked = false ;
360+ return r;
361+ } else {
362+ self . buf . extend_from_slice ( buf) ;
363+ total_written += buf. len ( ) ;
364+ }
365+ debug_assert ! ( total_written != 0 ) ;
366+ }
367+ for buf in iter {
368+ if buf. len ( ) >= self . buf . capacity ( ) {
369+ // This slice should be written directly, but we have
370+ // already buffered some of the input. Bail out,
371+ // expecting it to be handled as the first slice in the
372+ // next call to write_vectored.
373+ break ;
374+ } else {
375+ total_written += self . write_to_buf ( buf) ;
376+ if self . buf . capacity ( ) == self . buf . len ( ) {
377+ break ;
378+ }
379+ }
380+ }
381+ Ok ( total_written)
344382 }
345383 }
346384
0 commit comments