fix: release write lock before showing blocking error dialog#1637
Open
chindris-mihai-alexandru wants to merge 5 commits intoCapSoftware:mainfrom
Open
fix: release write lock before showing blocking error dialog#1637chindris-mihai-alexandru wants to merge 5 commits intoCapSoftware:mainfrom
chindris-mihai-alexandru wants to merge 5 commits intoCapSoftware:mainfrom
Conversation
When a recording fails, the error handler acquires state_mtx.write() and then calls dialog.blocking_show(), holding the write lock for the entire duration the user is looking at the error popup. Any attempt to start a new recording blocks at state_mtx.read() indefinitely, forcing the user to quit and relaunch the app. Fix: run handle_recording_end() inside a scoped block so the write lock is dropped before the blocking dialog is shown. This allows users to immediately start a new recording after dismissing the error dialog. Closes CapSoftware#1535 (partial — fixes the secondary deadlock, not the root AVAssetWriter/WriterFailed error)
| Err(e) => { | ||
| let mut state = state_mtx.write().await; | ||
|
|
||
| let _ = RecordingEvent::Failed { |
There was a problem hiding this comment.
Minor cleanup: e.to_string() is computed 3x here; consider computing it once and reusing it (also keeps the error message consistent across event/state cleanup/dialog).
Suggested change
| let _ = RecordingEvent::Failed { | |
| Err(e) => { | |
| let error = e.to_string(); | |
| let _ = RecordingEvent::Failed { | |
| error: error.clone(), | |
| } | |
| .emit(&app); | |
| { | |
| let mut state = state_mtx.write().await; | |
| let _ = handle_recording_end( | |
| app.clone(), | |
| Err(error.clone()), | |
| &mut state, | |
| project_file_path, | |
| ) | |
| .await; | |
| } | |
| let mut dialog = MessageDialogBuilder::new( | |
| app.dialog().clone(), | |
| "An error occurred".to_string(), | |
| error, | |
| ) | |
| .kind(tauri_plugin_dialog::MessageDialogKind::Error); |
Author
There was a problem hiding this comment.
Applied in 7beab87. I now compute the error string once and reuse it for the failed event payload, cleanup path, and dialog message.
Co-authored-by: tembo[bot] <208362400+tembo[bot]@users.noreply.github.com>
Co-authored-by: tembo[bot] <208362400+tembo[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
state_mtx.write().awaitis acquired, thendialog.blocking_show()is called while still holding the lock — blocking any new recording attempt atstate_mtx.read().awaitindefinitelyProblem
When a recording fails (e.g. due to
WriterFailed/ AVAssetWriter errors as reported in #1535), the error handler inrecording.rsdoes:state_mtx.write().awaitFailedeventdialog.blocking_show())handle_recording_end()and release the lockSince the write lock is held for the entire duration the user is looking at the error popup, any attempt to start a new recording blocks at
state_mtx.read().await— the app appears frozen and the user must force-quit and relaunch.Fix
Restructure the error handler to:
Failedeventhandle_recording_end()to clean up state, then drop the lockThis allows users to immediately start a new recording after dismissing the error dialog.
Testing
cargo check -p cap-desktoppassesRelated: #1535 (this fixes the secondary deadlock that compounds the WriterFailed issue)
Greptile Summary
Fixed a critical deadlock in the recording error handler by restructuring lock acquisition and dialog display order.
Key Changes:
state_mtx.write().awaitacquisition into a scoped block after event emissionhandle_recording_end) now executes within the scoped block, ensuring lock is dropped before the blocking dialogTechnical Details:
The previous code held a write lock during
dialog.blocking_show(), which blocked any attempt to start a new recording atstate_mtx.read().await. The fix ensures the lock is held only during cleanup, not during user interaction with the dialog. This allows the app to remain responsive after an error occurs.Confidence Score: 5/5
Important Files Changed
Last reviewed commit: 163e51c