Skip to content
Open
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
88f67e4
chore(common) Rename `CrossProcessLockKind` to `CrossProcessLockState`.
Hywan Nov 11, 2025
14aad28
feat(common) Add `#[must_use]` on `CrossProcessLockGuard` and `*State`.
Hywan Nov 11, 2025
6a2af4a
feat(common): Add `CrossProcessLockState::map`.
Hywan Nov 11, 2025
9c46b96
feat(base) Create the `EventCacheStoreLockState` type.
Hywan Nov 11, 2025
7ea191d
chore(sdk): Clean up imports.
Hywan Nov 11, 2025
32f136b
feat(common): Add `CrossProcessLockGuard::is_dirty` and `::clear_dirty`.
Hywan Nov 11, 2025
f5710f4
feat(base): Add `EventCacheStoreLockGuard::clear_dirty`.
Hywan Nov 11, 2025
87fa020
refactor(base): `EventCacheStoreLockState` owns a clone of the inner …
Hywan Nov 11, 2025
a48edd2
feat(common): `CrossProcessLockGuard` can be cloned.
Hywan Nov 12, 2025
ea3798a
feat(base): `EventCacheStoreLockGuard` can be cloned.
Hywan Nov 12, 2025
07b095d
fix(base): Use the `EventCacheStoreLockState`.
Hywan Nov 11, 2025
8b612cc
test(sdk): Update to use `EventCacheStoreLockState`.
Hywan Nov 11, 2025
56706ac
refactor(sdk) Introduce `RoomEventCacheStateLock` and read/write guards.
Hywan Nov 12, 2025
046e05f
feat(sdk): Reset `RoomEventCacheState` when the cross-process lock is…
Hywan Nov 18, 2025
3c4afc1
doc(sdk): Add missing or fix documentation.
Hywan Nov 18, 2025
f288e5f
fix(sdk): Remove a warning for `wasm32`.
Hywan Nov 18, 2025
8ee41f4
test(common): Test dirtiness of the cross-process lock.
Hywan Nov 18, 2025
ebbd1fe
test(common): Make tests run faster.
Hywan Nov 19, 2025
900f084
feat(sdk): Implement `RoomEventCacheStateLockWriteGuard::downgrade`.
Hywan Nov 19, 2025
6163013
feat(sdk): Allow shared access on `RoomEventCacheStateLock::read`.
Hywan Nov 19, 2025
cf881ab
test(sdk): Add the `test_reset_when_dirty` test.
Hywan Nov 19, 2025
7a163c1
refactor(sdk): Rename `RoomEventCacheInner::sender` to `update_sender`.
Hywan Nov 21, 2025
a32724b
feat(sdk): Send updates when `RoomEventCacheStateLock` is reloaded.
Hywan Nov 21, 2025
a6eae60
test(sdk): Ensure `EventCacheStoreLockGuard::clear_dirty` is called!
Hywan Nov 21, 2025
82fd99d
test(sdk): Add a test for dirtiness handling in `RoomEventCacheStateL…
Hywan Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions crates/matrix-sdk/src/event_cache/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,10 @@ mod private {
/// [`EventLinkedChunk`] relies on a [`LinkedChunk`] to store all
/// events. Only the last chunk will be loaded. It means the
/// events are loaded from the most recent to the oldest. To
/// load more events, see [`Self::load_more_events_backwards`].
/// load more events, see [`RoomPagination`].
///
/// [`LinkedChunk`]: matrix_sdk_common::linked_chunk::LinkedChunk
/// [`RoomPagination`]: super::RoomPagination
pub async fn new(
room_id: OwnedRoomId,
room_version_rules: RoomVersionRules,
Expand All @@ -729,10 +730,11 @@ mod private {
pagination_status: SharedObservable<RoomPaginationStatus>,
) -> Result<Self, EventCacheError> {
let store_guard = match store.lock().await? {
//
// Lock is clean: all good!
EventCacheStoreLockState::Clean(guard) => guard,

//
// Lock is dirty, not a problem, it's the first time we are creating this state, no
// need to refresh.
EventCacheStoreLockState::Dirty(guard) => {
EventCacheStoreLockGuard::clear_dirty(&guard);

Expand Down Expand Up @@ -812,6 +814,15 @@ mod private {
})
}

/// Lock this [`RoomEventCacheStateLock`] with per-thread shared access.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this really have per-thread shared access given it calls let state_guard = self.locked_state.write().await; inside?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first write lock is transformed to a read lock as soon as possible. The result for the caller is indeed a per-thread shared access.

///
/// This method locks the per-thread lock over the state, and then locks
/// the cross-process lock over the store. It returns an RAII guard
/// which will drop the read access to the state and to the store when
/// dropped.
///
/// If the cross-process lock over the store is dirty (see
/// [`EventCacheStoreLockState`]), the state is reset to the last chunk.
pub async fn read(&self) -> Result<RoomEventCacheStateLockReadGuard<'_>, EventCacheError> {
// Take a write-lock in case the lock is dirty and we need to reset the state.
let state_guard = self.locked_state.write().await;
Expand Down Expand Up @@ -843,6 +854,16 @@ mod private {
}
}

/// Lock this [`RoomEventCacheStateLock`] with exclusive per-thread
/// write access.
///
/// This method locks the per-thread lock over the state, and then locks
/// the cross-process lock over the store. It returns an RAII guard
/// which will drop the write access to the state and to the store when
/// dropped.
///
/// If the cross-process lock over the store is dirty (see
/// [`EventCacheStoreLockState`]), the state is reset to the last chunk.
pub async fn write(
&self,
) -> Result<RoomEventCacheStateLockWriteGuard<'_>, EventCacheError> {
Expand All @@ -868,13 +889,23 @@ mod private {
}
}

/// The read lock guard returned by [`RoomEventCacheStateLock::read`].
pub struct RoomEventCacheStateLockReadGuard<'a> {
/// The per-thread read lock guard over the
/// [`RoomEventCacheStateLockInner`].
state: RwLockReadGuard<'a, RoomEventCacheStateLockInner>,

/// The cross-process lock guard over the store.
store: EventCacheStoreLockGuard,
}

/// The write lock guard return by [`RoomEventCacheStateLock::write`].
pub struct RoomEventCacheStateLockWriteGuard<'a> {
/// The per-thread write lock guard over the
/// [`RoomEventCacheStateLockInner`].
state: RwLockWriteGuard<'a, RoomEventCacheStateLockInner>,

/// The cross-process lock guard over the store.
store: EventCacheStoreLockGuard,
}

Expand Down Expand Up @@ -947,6 +978,7 @@ mod private {
&mut self.state.room_linked_chunk
}

/// Get a reference to the `waited_for_initial_prev_token` atomic bool.
pub fn waited_for_initial_prev_token(&self) -> &Arc<AtomicBool> {
&self.state.waited_for_initial_prev_token
}
Expand Down