Skip to content

Commit bd6c35b

Browse files
Darksonnseanmonstar
authored andcommittedOct 18, 2021
fix(client): make ResponseFuture implement Sync
1 parent d0c6aaa commit bd6c35b

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed
 

‎src/client/client.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use super::pool::{
1818
#[cfg(feature = "tcp")]
1919
use super::HttpConnector;
2020
use crate::body::{Body, HttpBody};
21-
use crate::common::{exec::BoxSendFuture, lazy as hyper_lazy, task, Future, Lazy, Pin, Poll};
21+
use crate::common::{exec::BoxSendFuture, sync_wrapper::SyncWrapper, lazy as hyper_lazy, task, Future, Lazy, Pin, Poll};
2222
use crate::rt::Executor;
2323

2424
/// A Client to make outgoing HTTP requests.
@@ -45,7 +45,7 @@ struct Config {
4545
/// This is returned by `Client::request` (and `Client::get`).
4646
#[must_use = "futures do nothing unless polled"]
4747
pub struct ResponseFuture {
48-
inner: Pin<Box<dyn Future<Output = crate::Result<Response<Body>>> + Send>>,
48+
inner: SyncWrapper<Pin<Box<dyn Future<Output = crate::Result<Response<Body>>> + Send>>>,
4949
}
5050

5151
// ===== impl Client =====
@@ -168,9 +168,9 @@ where
168168
Version::HTTP_10 => {
169169
if is_http_connect {
170170
warn!("CONNECT is not allowed for HTTP/1.0");
171-
return ResponseFuture::new(Box::pin(future::err(
171+
return ResponseFuture::new(future::err(
172172
crate::Error::new_user_unsupported_request_method(),
173-
)));
173+
));
174174
}
175175
}
176176
Version::HTTP_2 => (),
@@ -181,11 +181,11 @@ where
181181
let pool_key = match extract_domain(req.uri_mut(), is_http_connect) {
182182
Ok(s) => s,
183183
Err(err) => {
184-
return ResponseFuture::new(Box::pin(future::err(err)));
184+
return ResponseFuture::new(future::err(err));
185185
}
186186
};
187187

188-
ResponseFuture::new(Box::pin(self.clone().retryably_send_request(req, pool_key)))
188+
ResponseFuture::new(self.clone().retryably_send_request(req, pool_key))
189189
}
190190

191191
async fn retryably_send_request(
@@ -580,8 +580,13 @@ impl<C, B> fmt::Debug for Client<C, B> {
580580
// ===== impl ResponseFuture =====
581581

582582
impl ResponseFuture {
583-
fn new(fut: Pin<Box<dyn Future<Output = crate::Result<Response<Body>>> + Send>>) -> Self {
584-
Self { inner: fut }
583+
fn new<F>(value: F) -> Self
584+
where
585+
F: Future<Output = crate::Result<Response<Body>>> + Send + 'static,
586+
{
587+
Self {
588+
inner: SyncWrapper::new(Box::pin(value))
589+
}
585590
}
586591

587592
fn error_version(ver: Version) -> Self {
@@ -602,7 +607,7 @@ impl Future for ResponseFuture {
602607
type Output = crate::Result<Response<Body>>;
603608

604609
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
605-
Pin::new(&mut self.inner).poll(cx)
610+
self.inner.get_mut().as_mut().poll(cx)
606611
}
607612
}
608613

@@ -1276,6 +1281,12 @@ impl fmt::Debug for Builder {
12761281
mod unit_tests {
12771282
use super::*;
12781283

1284+
#[test]
1285+
fn response_future_is_sync() {
1286+
fn assert_sync<T: Sync>() {}
1287+
assert_sync::<ResponseFuture>();
1288+
}
1289+
12791290
#[test]
12801291
fn set_relative_uri_with_implicit_path() {
12811292
let mut uri = "http://hyper.rs".parse().unwrap();

‎src/common/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ pub(crate) mod io;
1818
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
1919
mod lazy;
2020
mod never;
21-
#[cfg(feature = "stream")]
21+
#[cfg(any(
22+
feature = "stream",
23+
all(feature = "client", any(feature = "http1", feature = "http2"))
24+
))]
2225
pub(crate) mod sync_wrapper;
2326
pub(crate) mod task;
2427
pub(crate) mod watch;

0 commit comments

Comments
 (0)
Please sign in to comment.