Skip to content

Commit cbc8b99

Browse files
authored
Merge pull request #10606 from dantengsky/fix-dead-lock-session-destruction
fix: deadlock in session destruction
2 parents 7c3018e + b593175 commit cbc8b99

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/query/service/src/sessions/session_mgr.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,27 @@ impl SessionManager {
213213
}
214214

215215
pub fn processes_info(&self) -> Vec<ProcessInfo> {
216-
let sessions = self.active_sessions.read();
216+
let active_sessions = {
217+
// Here the situation is the same of method `graceful_shutdown`:
218+
//
219+
// We should drop the read lock before
220+
// - acquiring upgraded session reference: the Arc<Session>,
221+
// - extracting the ProcessInfo from it
222+
// - and then drop the Arc<Session>
223+
// Since there are chances that we are the last one that holding the reference, and the
224+
// destruction of session need to acquire the write lock of `active_sessions`, which leads
225+
// to dead lock.
226+
//
227+
// Although online expression can also do this, to make this clearer, we wrap it in a block
228+
229+
let active_sessions_guard = self.active_sessions.read();
230+
active_sessions_guard.values().cloned().collect::<Vec<_>>()
231+
};
217232

218-
let mut processes_info = Vec::with_capacity(sessions.len());
219-
for weak_ptr in sessions.values() {
220-
if let Some(active_session) = weak_ptr.upgrade() {
221-
processes_info.push(active_session.process_info());
222-
}
223-
}
224-
225-
processes_info
233+
active_sessions
234+
.into_iter()
235+
.filter_map(|weak_ptr| weak_ptr.upgrade().map(|session| session.process_info()))
236+
.collect::<Vec<_>>()
226237
}
227238

228239
fn destroy_idle_sessions(sessions: &Arc<RwLock<HashMap<String, Weak<Session>>>>) -> bool {

0 commit comments

Comments
 (0)