Skip to content

Commit 4613ff2

Browse files
SnarpixBenxiang Ge
authored and
Benxiang Ge
committed
feat(lib): Setting http1_writev(true) will now force writev queue usage
Previously, calling `http1_writev(true)` would just keep the default behavior, which was to auto detect if writev was optimal. Now, the auto-detection is still default, but explicitly calling `http1_writev(true)` will skip the auto-detection, and always use writev queue strategy. Closes hyperium#2282
1 parent c9c7ec3 commit 4613ff2

File tree

6 files changed

+44
-13
lines changed

6 files changed

+44
-13
lines changed

src/client/conn.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ where
7575
#[derive(Clone, Debug)]
7676
pub struct Builder {
7777
pub(super) exec: Exec,
78-
h1_writev: bool,
78+
h1_writev: Option<bool>,
7979
h1_title_case_headers: bool,
8080
h1_read_buf_exact_size: Option<usize>,
8181
h1_max_buf_size: Option<usize>,
@@ -424,7 +424,7 @@ impl Builder {
424424
pub fn new() -> Builder {
425425
Builder {
426426
exec: Exec::Default,
427-
h1_writev: true,
427+
h1_writev: None,
428428
h1_read_buf_exact_size: None,
429429
h1_title_case_headers: false,
430430
h1_max_buf_size: None,
@@ -443,7 +443,7 @@ impl Builder {
443443
}
444444

445445
pub(super) fn h1_writev(&mut self, enabled: bool) -> &mut Builder {
446-
self.h1_writev = enabled;
446+
self.h1_writev = Some(enabled);
447447
self
448448
}
449449

@@ -609,8 +609,12 @@ impl Builder {
609609
let (tx, rx) = dispatch::channel();
610610
let proto = if !opts.http2 {
611611
let mut conn = proto::Conn::new(io);
612-
if !opts.h1_writev {
613-
conn.set_write_strategy_flatten();
612+
if let Some(writev) = opts.h1_writev {
613+
if writev {
614+
conn.set_write_strategy_queue();
615+
} else {
616+
conn.set_write_strategy_flatten();
617+
}
614618
}
615619
if opts.h1_title_case_headers {
616620
conn.set_title_case_headers();

src/client/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,11 @@ impl Builder {
964964
/// but may also improve performance when an IO transport doesn't
965965
/// support vectored writes well, such as most TLS implementations.
966966
///
967-
/// Default is `true`.
967+
/// Setting this to true will force hyper to use queued strategy
968+
/// which may eliminate unnecessary cloning on some TLS backends
969+
///
970+
/// Default is `auto`. In this mode hyper will try to guess which
971+
/// mode to use
968972
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
969973
self.conn_builder.h1_writev(val);
970974
self

src/proto/h1/conn.rs

+4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ where
7373
self.io.set_write_strategy_flatten();
7474
}
7575

76+
pub fn set_write_strategy_queue(&mut self) {
77+
self.io.set_write_strategy_queue();
78+
}
79+
7680
pub fn set_title_case_headers(&mut self) {
7781
self.state.title_case_headers = true;
7882
}

src/proto/h1/io.rs

+7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ where
9494
self.write_buf.set_strategy(WriteStrategy::Flatten);
9595
}
9696

97+
pub fn set_write_strategy_queue(&mut self) {
98+
// this should always be called only at construction time,
99+
// so this assert is here to catch myself
100+
debug_assert!(self.write_buf.queue.bufs_cnt() == 0);
101+
self.write_buf.set_strategy(WriteStrategy::Queue);
102+
}
103+
97104
pub fn read_buf(&self) -> &[u8] {
98105
self.read_buf.as_ref()
99106
}

src/server/conn.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub struct Http<E = Exec> {
8181
exec: E,
8282
h1_half_close: bool,
8383
h1_keep_alive: bool,
84-
h1_writev: bool,
84+
h1_writev: Option<bool>,
8585
h2_builder: proto::h2::server::Config,
8686
mode: ConnectionMode,
8787
max_buf_size: Option<usize>,
@@ -217,7 +217,7 @@ impl Http {
217217
exec: Exec::Default,
218218
h1_half_close: false,
219219
h1_keep_alive: true,
220-
h1_writev: true,
220+
h1_writev: None,
221221
h2_builder: Default::default(),
222222
mode: ConnectionMode::Fallback,
223223
max_buf_size: None,
@@ -274,10 +274,14 @@ impl<E> Http<E> {
274274
/// but may also improve performance when an IO transport doesn't
275275
/// support vectored writes well, such as most TLS implementations.
276276
///
277-
/// Default is `true`.
277+
/// Setting this to true will force hyper to use queued strategy
278+
/// which may eliminate unnecessary cloning on some TLS backends
279+
///
280+
/// Default is `auto`. In this mode hyper will try to guess which
281+
/// mode to use
278282
#[inline]
279283
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
280-
self.h1_writev = val;
284+
self.h1_writev = Some(val);
281285
self
282286
}
283287

@@ -487,8 +491,12 @@ impl<E> Http<E> {
487491
if self.h1_half_close {
488492
conn.set_allow_half_close();
489493
}
490-
if !self.h1_writev {
491-
conn.set_write_strategy_flatten();
494+
if let Some(writev) = self.h1_writev {
495+
if writev {
496+
conn.set_write_strategy_queue();
497+
} else {
498+
conn.set_write_strategy_flatten();
499+
}
492500
}
493501
conn.set_flush_pipeline(self.pipeline_flush);
494502
if let Some(max) = self.max_buf_size {

src/server/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,11 @@ impl<I, E> Builder<I, E> {
286286
/// but may also improve performance when an IO transport doesn't
287287
/// support vectored writes well, such as most TLS implementations.
288288
///
289-
/// Default is `true`.
289+
/// Setting this to true will force hyper to use queued strategy
290+
/// which may eliminate unnecessary cloning on some TLS backends
291+
///
292+
/// Default is `auto`. In this mode hyper will try to guess which
293+
/// mode to use
290294
pub fn http1_writev(mut self, val: bool) -> Self {
291295
self.protocol.http1_writev(val);
292296
self

0 commit comments

Comments
 (0)