Skip to content

Commit 7171b37

Browse files
committed
refactor(sdk): Change a Semaphore(permit=1) for a Mutex.
This patch changes the `Semaphore(permit=1)` for a `Mutex`: the semantics is strictly equivalent, but it removes the need to guarantee there is a single permit.
1 parent 1e1ce2d commit 7171b37

File tree

1 file changed

+15
-25
lines changed
  • crates/matrix-sdk/src/event_cache/room

1 file changed

+15
-25
lines changed

crates/matrix-sdk/src/event_cache/room/mod.rs

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ mod private {
650650
serde::Raw,
651651
};
652652
use tokio::sync::{
653-
RwLock, RwLockReadGuard, RwLockWriteGuard, Semaphore,
653+
Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard,
654654
broadcast::{Receiver, Sender},
655655
};
656656
use tracing::{debug, error, instrument, trace, warn};
@@ -678,7 +678,7 @@ mod private {
678678

679679
/// Please see inline comment of [`Self::read`] to understand why it
680680
/// exists.
681-
read_lock_acquisition: Semaphore,
681+
read_lock_acquisition: Mutex<()>,
682682
}
683683

684684
struct RoomEventCacheStateLockInner {
@@ -838,7 +838,7 @@ mod private {
838838
waited_for_initial_prev_token,
839839
subscriber_count: Default::default(),
840840
}),
841-
read_lock_acquisition: Semaphore::new(1),
841+
read_lock_acquisition: Mutex::new(()),
842842
})
843843
}
844844

@@ -860,10 +860,10 @@ mod private {
860860
// ## Upgradable read lock
861861
//
862862
// One may argue that this upgrades can be done with an _upgradable read lock_
863-
// [^1] [^2]. We don't want to use this solution because an upgradable read lock
864-
// is basically a mutex because we are losing the shared access property: having
865-
// multiple read locks at the same time. This is an important property to hold
866-
// for performance concerns.
863+
// [^1] [^2]. We don't want to use this solution: an upgradable read lock is
864+
// basically a mutex because we are losing the shared access property, i.e.
865+
// having multiple read locks at the same time. This is an important property to
866+
// hold for performance concerns.
867867
//
868868
// ## Downgradable write lock
869869
//
@@ -886,30 +886,19 @@ mod private {
886886
// new lock acquisition, and it's not possible to pause the runtime in the
887887
// meantime.
888888
//
889-
// ## Semaphore
889+
// ## Semaphore with 1 permit, aka a Mutex
890890
//
891-
// The chosen idea is to allow only one execution at a time of this method. That
892-
// way we are free to “upgrade” the read lock by dropping it and obtaining a new
893-
// write lock. All callers to this method are waiting, so nothing can happen in
894-
// the meantime.
891+
// The chosen idea is to allow only one execution at a time of this method: it
892+
// becomes a critical section. That way we are free to “upgrade” the read lock
893+
// by dropping it and obtaining a new write lock. All callers to this method are
894+
// waiting, so nothing can happen in the meantime.
895895
//
896896
// Note that it doesn't conflict with the `write` method because this later
897897
// immediately obtains a write lock, which avoids any conflict with this method.
898898
//
899899
// [^1]: https://docs.rs/lock_api/0.4.14/lock_api/struct.RwLock.html#method.upgradable_read
900900
// [^2]: https://docs.rs/async-lock/3.4.1/async_lock/struct.RwLock.html#method.upgradable_read
901-
let _permit = self
902-
.read_lock_acquisition
903-
.acquire()
904-
.await
905-
.expect("The `lock_acquisition` semaphore must never be closed");
906-
907-
// Just a check in case the code is modified without knowing how it works.
908-
debug_assert_eq!(
909-
self.read_lock_acquisition.available_permits(),
910-
0,
911-
"The semaphore must have only one permit"
912-
);
901+
let _one_reader_guard = self.read_lock_acquisition.lock().await;
913902

914903
// Obtain a read lock.
915904
let state_guard = self.locked_state.read().await;
@@ -920,7 +909,8 @@ mod private {
920909
}
921910
EventCacheStoreLockState::Dirty(store_guard) => {
922911
// Drop the read lock, and take a write lock to modify the state.
923-
// This is safe because only one semaphore permit exists.
912+
// This is safe because only one reader at a time (see
913+
// `Self::read_lock_acquisition`) is allowed.
924914
drop(state_guard);
925915
let state_guard = self.locked_state.write().await;
926916

0 commit comments

Comments
 (0)