diff options
author | François Laignel <fengalin@free.fr> | 2021-12-19 15:18:50 +0300 |
---|---|---|
committer | Sebastian Dröge <slomo@coaxion.net> | 2021-12-20 12:01:09 +0300 |
commit | a1c89dd17b6bf4b0d6f3d785fcad71eec9b12dd7 (patch) | |
tree | 12c89e31f1e4b583f1e4f2c0edf9b44f35a26a8d /utils | |
parent | 82d969190f40bb06770e627ea831584ffc26789a (diff) |
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.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/togglerecord/src/togglerecord/imp.rs | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/utils/togglerecord/src/togglerecord/imp.rs b/utils/togglerecord/src/togglerecord/imp.rs index 2583a7ffd..36074b90e 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(); |