Skip to content

Commit e07edce

Browse files
committed
fix: address a deadlock in h1 pooling
Beforehand, the underlying `RwLockReadGuard` was alive until the end of any connection. This drops the guard before we start doing IO.
1 parent f133517 commit e07edce

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/h1/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ impl HttpClient for H1Client {
102102

103103
match scheme {
104104
"http" => {
105-
let pool = if let Some(pool) = self.http_pools.get(&addr) {
106-
pool
105+
let pool_ref = if let Some(pool_ref) = self.http_pools.get(&addr) {
106+
pool_ref
107107
} else {
108108
let manager = TcpConnection::new(addr);
109109
let pool = Pool::<TcpStream, std::io::Error>::new(
@@ -113,15 +113,19 @@ impl HttpClient for H1Client {
113113
self.http_pools.insert(addr, pool);
114114
self.http_pools.get(&addr).unwrap()
115115
};
116-
let pool = pool.clone();
116+
117+
// Deadlocks are prevented by cloning an inner pool Arc and dropping the original locking reference before we await.
118+
let pool = pool_ref.clone();
119+
std::mem::drop(pool_ref);
120+
117121
let stream = pool.get().await?;
118122
req.set_peer_addr(stream.peer_addr().ok());
119123
req.set_local_addr(stream.local_addr().ok());
120124
client::connect(TcpConnWrapper::new(stream), req).await
121125
}
122126
"https" => {
123-
let pool = if let Some(pool) = self.https_pools.get(&addr) {
124-
pool
127+
let pool_ref = if let Some(pool_ref) = self.https_pools.get(&addr) {
128+
pool_ref
125129
} else {
126130
let manager = TlsConnection::new(host.clone(), addr);
127131
let pool = Pool::<TlsStream<TcpStream>, Error>::new(
@@ -131,7 +135,11 @@ impl HttpClient for H1Client {
131135
self.https_pools.insert(addr, pool);
132136
self.https_pools.get(&addr).unwrap()
133137
};
134-
let pool = pool.clone();
138+
139+
// Deadlocks are prevented by cloning an inner pool Arc and dropping the original locking reference before we await.
140+
let pool = pool_ref.clone();
141+
std::mem::drop(pool_ref);
142+
135143
let stream = pool
136144
.get()
137145
.await

0 commit comments

Comments
 (0)