Don't use a static for the mark_room_as_dm lock

Using a static lock would prevent two Client instances to call the
method at the same time.

We're going to assume that people won't have multiple Client instances
for the same user, in which case a static lock would have been helpful.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
This commit is contained in:
Damir Jelić
2023-09-28 12:11:12 +02:00
parent bcbb7c61f8
commit e37cfe6036
2 changed files with 19 additions and 7 deletions

View File

@@ -47,7 +47,6 @@ use ruma::{
ClientSecret, MxcUri, OwnedMxcUri, OwnedUserId, RoomId, SessionId, UInt, UserId,
};
use serde::Deserialize;
use tokio::sync::Mutex;
use tracing::error;
use crate::{config::RequestConfig, Client, Error, HttpError, Result};
@@ -821,9 +820,7 @@ impl Account {
// To prevent multiple calls to this method trying to update the map of DMs same
// time, and thus trampling on each other we introduce a lock which acts
// as a semaphore.
static LOCK: Mutex<()> = Mutex::const_new(());
let _guard = LOCK.lock().await;
let _guard = self.client.locks().mark_as_dm_lock.lock().await;
// Now we need to mark the room as a DM for ourselves, we fetch the
// existing `m.direct` event and append the room to the list of DMs we

View File

@@ -65,9 +65,7 @@ use ruma::{
ServerName, UInt, UserId,
};
use serde::de::DeserializeOwned;
#[cfg(feature = "e2e-encryption")]
use tokio::sync::Mutex;
use tokio::sync::{broadcast, OnceCell, RwLock, RwLockReadGuard};
use tokio::sync::{broadcast, Mutex, OnceCell, RwLock, RwLockReadGuard};
use tracing::{debug, error, instrument, trace, Instrument, Span};
use url::Url;
@@ -144,6 +142,14 @@ pub struct Client {
pub(crate) inner: Arc<ClientInner>,
}
#[derive(Default)]
pub(crate) struct ClientLocks {
/// Lock ensuring that only a single room may be marked as a DM at once.
/// Look at the [`Room::mark_as_dm()`] method for a more detailed
/// explanation.
pub(crate) mark_as_dm_lock: Mutex<()>,
}
pub(crate) struct ClientInner {
/// All the data related to authentication and authorization.
pub(crate) auth_ctx: Arc<AuthCtx>,
@@ -159,6 +165,10 @@ pub(crate) struct ClientInner {
base_client: BaseClient,
/// The Matrix versions the server supports (well-known ones only)
server_versions: OnceCell<Box<[MatrixVersion]>>,
/// Collection of locks individual client methods might want to use, either
/// to ensure that only a single call to a method happens at once or to
/// deduplicate multiple calls to a method.
locks: ClientLocks,
/// Handler making sure we only have one group session sharing request in
/// flight per room.
#[cfg(feature = "e2e-encryption")]
@@ -238,6 +248,7 @@ impl ClientInner {
sliding_sync_proxy: StdRwLock::new(sliding_sync_proxy),
http_client,
base_client,
locks: Default::default(),
server_versions: OnceCell::new_with(server_versions),
#[cfg(feature = "e2e-encryption")]
group_session_deduplicated_handler: Default::default(),
@@ -296,6 +307,10 @@ impl Client {
&self.inner.base_client
}
pub(crate) fn locks(&self) -> &ClientLocks {
&self.inner.locks
}
/// Change the homeserver URL used by this client.
///
/// # Arguments