From a3424a7c4a8f8b1c0deeecfc69a3ff2bc3135765 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 11 Nov 2025 14:34:53 +0100 Subject: [PATCH] feat(base): Explicitly handle the `CrossProcessLockKind::Dirty` case in `MediaStore`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch replaces the `into_guard()` call by a `match` over `CrossProcessLockKind` so that the `Dirty` case is explicitly handled. The mid-term idea is to remove the `into_guard()` method because it is “dangerous” as it hides the `Dirty` case. --- crates/matrix-sdk-base/src/media/store/mod.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-base/src/media/store/mod.rs b/crates/matrix-sdk-base/src/media/store/mod.rs index 6c4cf56ca..b861673e8 100644 --- a/crates/matrix-sdk-base/src/media/store/mod.rs +++ b/crates/matrix-sdk-base/src/media/store/mod.rs @@ -33,7 +33,7 @@ use std::{ops::Deref, sync::Arc}; use matrix_sdk_common::cross_process_lock::{ CrossProcessLock, CrossProcessLockError, CrossProcessLockGeneration, CrossProcessLockGuard, - TryLock, + CrossProcessLockKind, TryLock, }; use matrix_sdk_store_encryption::Error as StoreEncryptionError; pub use traits::{DynMediaStore, IntoMediaStore, MediaStore, MediaStoreInner}; @@ -133,7 +133,20 @@ impl MediaStoreLock { /// Acquire a spin lock (see [`CrossProcessLock::spin_lock`]). pub async fn lock(&self) -> Result, CrossProcessLockError> { - let cross_process_lock_guard = self.cross_process_lock.spin_lock(None).await??.into_guard(); + let cross_process_lock_guard = match self.cross_process_lock.spin_lock(None).await?? { + // The lock is clean: no other hold acquired it, all good! + CrossProcessLockKind::Clean(guard) => guard, + + // The lock is dirty: another holder acquired it since the last time we acquired it. + // It's not a problem in the case of the `MediaStore` because this API is “stateless” at + // the time of writing (2025-11-11). There is nothing that can be out-of-sync: all the + // state is in the database, nothing in memory. + CrossProcessLockKind::Dirty(guard) => { + self.cross_process_lock.clear_dirty(); + + guard + } + }; Ok(MediaStoreLockGuard { cross_process_lock_guard, store: self.store.deref() }) }