From a1c89dd17b6bf4b0d6f3d785fcad71eec9b12dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Sun, 19 Dec 2021 13:18:50 +0100 Subject: [PATCH] utils/togglerecord: fix race condition checking other streams EOS state Function `check_and_update_stream_start` checks whether other streams reached EOS. The stream being checked might already have locked its state. If it's about to check other streams too, this results in a deadlock. The problem was due to the `main_state` guard being dropped handling event `StreamStart` checking whether the main stream is EOS: ```rust let main_is_eos = if let Some(main_state) = main_state { main_state.eos } else { false }; ``` In the above code, `main_state` main state is comsumed and dropped after evaluating `main_state.eos`. This is also the case before handling event `Eos`. This revealed another deadlock handling event `Eos` which is under investigation. --- utils/togglerecord/src/togglerecord/imp.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/utils/togglerecord/src/togglerecord/imp.rs b/utils/togglerecord/src/togglerecord/imp.rs index 2583a7ff..36074b90 100644 --- a/utils/togglerecord/src/togglerecord/imp.rs +++ b/utils/togglerecord/src/togglerecord/imp.rs @@ -1410,11 +1410,9 @@ impl ToggleRecord { let mut state = stream.state.lock(); state.eos = false; - let main_is_eos = if let Some(main_state) = main_state { - main_state.eos - } else { - false - }; + let main_is_eos = main_state + .as_ref() + .map_or(false, |main_state| main_state.eos); if !main_is_eos { let mut rec_state = self.state.lock(); @@ -1438,11 +1436,9 @@ impl ToggleRecord { let mut state = stream.state.lock(); state.eos = true; - let main_is_eos = if let Some(main_state) = main_state { - main_state.eos - } else { - true - }; + let main_is_eos = main_state + .as_ref() + .map_or(true, |main_state| main_state.eos); if main_is_eos { let mut rec_state = self.state.lock();