Repository navigation
Conversation
Package Changes Through dfe58b1There are 4 changes which include opener with patch, opener-js with patch, store with patch, store-js with patch Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
|
Could you provide a minimal reproducible example that we could test on? |
|
load holds the stores lock and waits for the resource table repro hangs on v2 after ~30s and passes here |
|
I see, thanks for the repro! This is quite tricky that we can't lock the resource table and state together 🤔 I'll take a closer look at the PR. Edit: I see, the locking order must always stay the same and both of them must always be locked together |
Legend-Master
left a comment
There was a problem hiding this comment.
Really nice catch, thanks! I have a few questions and we can get this merged.
| if self.create_new { | ||
| if let Some(rid) = stores.remove(&self.path) { | ||
| let _ = self.app.resources_table().take::<Store<R>>(rid); | ||
| if !self.create_new { |
There was a problem hiding this comment.
Is there any reason we did this check twice? here and below
load and close on the same store at the same time deadlock
close (
resources|close) holds the resource table then takesstores.write()load (
build_inner) holdsstores.write()for the whole build then locks the tableget_storeand the exit save loop use that order tooclose is a sync command so the main thread hangs and the app freezes for good
not the same as #3394 or #3570
fix
build_innerlooks up with a short read lock, builds with no lock held, then locks table first and stores second like close doesif another load of the same path won it returns that store so still one store per path
if a close lands between the lookup and the table get it builds a fresh one instead of failing with
BadResourceIdget_storeand the exit loop copy the rid out before touching the tablerepro without an app
hangs on v2 and v3 till its 30s timeout, ~0.05s here
real app on tauri 2.12.5 + store 2.5.0 from crates.io, page only calls load and close
before hung 5 of 8 runs, after 8 of 8 fine
hung run stack: main thread in
Store::closewaiting on the rwlock, tokio worker inbuild_innerwaiting on the table mutexa react strict mode or hmr remount can hit this from js alone, maybe #3361
behavior otherwise same (same rid on reload, createNew, parallel loads get one rid)
clippy fmt tests pass, macos only