@@ -328,19 +328,57 @@ impl<W: Write> Write for BufWriter<W> {
328
328
}
329
329
330
330
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
+ }
341
345
} 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)
344
382
}
345
383
}
346
384
0 commit comments