Skip to content

Commit 964e13f

Browse files
fix(store): dead lock trying to set while exiting (#3395)
* fix(store): dead lock trying to set while exiting * Add change file
1 parent e6cdc9f commit 964e13f

3 files changed

Lines changed: 16 additions & 10 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
store: patch
3+
store-js: patch
4+
---
5+
6+
Fix a deadlock when calling `Store::set` while exiting (on `RunEvent::Exit`)

plugins/store/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use serde_json::Value as JsonValue;
1515
use std::{
1616
collections::HashMap,
1717
path::{Path, PathBuf},
18-
sync::{Arc, Mutex},
18+
sync::{Arc, RwLock},
1919
time::Duration,
2020
};
2121
pub use store::{resolve_store_path, DeserializeFn, SerializeFn, Store, StoreBuilder};
@@ -39,7 +39,7 @@ struct ChangePayload<'a> {
3939

4040
#[derive(Debug)]
4141
struct StoreState {
42-
stores: Arc<Mutex<HashMap<PathBuf, ResourceId>>>,
42+
stores: Arc<RwLock<HashMap<PathBuf, ResourceId>>>,
4343
serialize_fns: HashMap<String, SerializeFn>,
4444
deserialize_fns: HashMap<String, DeserializeFn>,
4545
default_serialize: SerializeFn,
@@ -139,7 +139,7 @@ async fn get_store<R: Runtime>(
139139
store_state: State<'_, StoreState>,
140140
path: PathBuf,
141141
) -> Result<Option<ResourceId>> {
142-
let stores = store_state.stores.lock().unwrap();
142+
let stores = store_state.stores.read().unwrap();
143143
Ok(stores.get(&resolve_store_path(&app, path)?).copied())
144144
}
145145

@@ -317,7 +317,7 @@ impl<R: Runtime, T: Manager<R>> StoreExt<R> for T {
317317

318318
fn get_store(&self, path: impl AsRef<Path>) -> Option<Arc<Store<R>>> {
319319
let collection = self.state::<StoreState>();
320-
let stores = collection.stores.lock().unwrap();
320+
let stores = collection.stores.read().unwrap();
321321
stores
322322
.get(&resolve_store_path(self.app_handle(), path.as_ref()).ok()?)
323323
.and_then(|rid| self.resources_table().get(*rid).ok())
@@ -437,7 +437,7 @@ impl Builder {
437437
])
438438
.setup(move |app_handle, _api| {
439439
app_handle.manage(StoreState {
440-
stores: Arc::new(Mutex::new(HashMap::new())),
440+
stores: Arc::new(RwLock::new(HashMap::new())),
441441
serialize_fns: self.serialize_fns,
442442
deserialize_fns: self.deserialize_fns,
443443
default_serialize: self.default_serialize,
@@ -448,7 +448,7 @@ impl Builder {
448448
.on_event(|app_handle, event| {
449449
if let RunEvent::Exit = event {
450450
let collection = app_handle.state::<StoreState>();
451-
let stores = collection.stores.lock().unwrap();
451+
let stores = collection.stores.read().unwrap();
452452
for (path, rid) in stores.iter() {
453453
if let Ok(store) = app_handle.resources_table().get::<Store<R>>(*rid) {
454454
if let Err(err) = store.save() {

plugins/store/src/store.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl<R: Runtime> StoreBuilder<R> {
188188

189189
pub(crate) fn build_inner(mut self) -> crate::Result<(Arc<Store<R>>, ResourceId)> {
190190
let stores = self.app.state::<StoreState>().stores.clone();
191-
let mut stores = stores.lock().unwrap();
191+
let mut stores = stores.write().unwrap();
192192

193193
self.path = resolve_store_path(&self.app, self.path)?;
194194

@@ -403,7 +403,7 @@ impl<R: Runtime> StoreInner<R> {
403403

404404
fn emit_change_event(&self, key: &str, value: Option<&JsonValue>) -> crate::Result<()> {
405405
let state = self.app.state::<StoreState>();
406-
let stores = state.stores.lock().unwrap();
406+
let stores = state.stores.read().unwrap();
407407
let exists = value.is_some();
408408
self.app.emit(
409409
"store://change",
@@ -438,7 +438,7 @@ impl<R: Runtime> Resource for Store<R> {
438438
fn close(self: Arc<Self>) {
439439
let store = self.store.lock().unwrap();
440440
let state = store.app.state::<StoreState>();
441-
let mut stores = state.stores.lock().unwrap();
441+
let mut stores = state.stores.write().unwrap();
442442
stores.remove(&store.path);
443443
}
444444
}
@@ -554,7 +554,7 @@ impl<R: Runtime> Store<R> {
554554
let store = self.store.lock().unwrap();
555555
let app = store.app.clone();
556556
let state = app.state::<StoreState>();
557-
let stores = state.stores.lock().unwrap();
557+
let stores = state.stores.read().unwrap();
558558
if let Some(rid) = stores.get(&store.path).copied() {
559559
drop(store);
560560
drop(stores);

0 commit comments

Comments
 (0)