Skip to content

Commit c29fdbc

Browse files
authored
connection_status: fix deadlock when poisoning connection (#446)
When poisoning the connection status during an early network failure, we would end up dropping the connection held by the connection resolver while the ConnectionStatus is still locked. Make sure we always release the lock before dropping the connection so that the ConnectionCloser doesn't lock us when accessing the ConnectionStatus. Fixes #447
1 parent 81f07ae commit c29fdbc

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

src/connection_status.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ impl ConnectionStatus {
112112
}
113113

114114
pub(crate) fn poison(&self, err: Error) {
115-
self.lock_inner().poison(err);
115+
let resolver = self.lock_inner().poison(err.clone());
116+
if let Some((resolver, _connection)) = resolver {
117+
// We perform the reject here to drop the lock() above before dropping the Connection
118+
resolver.reject(err);
119+
}
116120
}
117121

118122
pub(crate) fn auto_close(&self) -> bool {
@@ -262,10 +266,9 @@ impl Inner {
262266
.map(ConnectionStep::into_connection_resolver)
263267
}
264268

265-
fn poison(&mut self, err: Error) {
266-
if let Some((resolver, _connection)) = self.connection_resolver() {
267-
resolver.reject(err.clone());
268-
}
269+
fn poison(&mut self, err: Error) -> Option<(ConnectionResolver, Option<Connection>)> {
269270
self.poison = Some(err);
271+
272+
self.connection_resolver()
270273
}
271274
}

0 commit comments

Comments
 (0)