7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 1 | // Copyright 2025 The Matrix.org Foundation C.I.C. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 2 | // |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 4 | // you may not use this file except in compliance with the License. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 5 | // You may obtain a copy of the License at |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 6 | // |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 8 | // |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 9 | // Unless required by applicable law or agreed to in writing, software |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 12 | // See the License for the specific language governing permissions and |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 13 | // limitations under the License. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 14 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 15 | //! Simplified locks hat panic instead of returning a `Result` when the lock is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 16 | //! poisoned. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 17 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 18 | use std::{ |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 19 | fmt, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 20 | sync::{Mutex as StdMutex, MutexGuard, RwLock as StdRwLock, RwLockReadGuard, RwLockWriteGuard}, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 21 | }; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 22 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 23 | use serde::{Deserialize, Serialize}; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 24 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 25 | /// A wrapper around `std::sync::Mutex` that panics on poison. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 26 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 27 | /// This `Mutex` works similarly to the standard library's `Mutex`, except its |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 28 | /// `lock` method does not return a `Result`. Instead, if the mutex is poisoned, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 29 | /// it will panic. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 30 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 31 | /// # Examples |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 32 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 33 | /// ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 34 | /// use matrix_sdk_common::locks::Mutex; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 35 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 36 | /// let mutex = Mutex::new(42); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 37 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 38 | /// { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 39 | /// let mut guard = mutex.lock(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 40 | /// *guard = 100; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 41 | /// } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 42 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 43 | /// assert_eq!(*mutex.lock(), 100); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 44 | /// ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 45 | #[derive(Default)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 46 | pub struct Mutex<T: ?Sized>(StdMutex<T>); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 47 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 48 | impl<T> Mutex<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 49 | /// Creates a new `Mutex` wrapping the given value. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 50 | pub const fn new(t: T) -> Self { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 51 | Self(StdMutex::new(t)) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 52 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 53 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 54 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 55 | impl<T: ?Sized> Mutex<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 56 | /// Acquires the lock, panicking if the lock is poisoned. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 57 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 58 | /// This method blocks the current thread until the lock is acquired. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 59 | pub fn lock(&self) -> MutexGuard<'_, T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 60 | self.0.lock().expect("The Mutex should never be poisoned") |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 61 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 62 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 63 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 64 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 65 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 66 | self.0.fmt(f) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 67 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 68 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 69 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 70 | /// A wrapper around [`std::sync::RwLock`] that panics on poison. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 71 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 72 | /// This `RwLock` works similarly to the standard library's `RwLock`, except its |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 73 | /// `read` and `write` methods do not return a `Result`. Instead, if the lock is |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 74 | /// poisoned, it will panic. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 75 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 76 | /// # Examples |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 77 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 78 | /// ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 79 | /// use matrix_sdk_common::locks::RwLock; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 80 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 81 | /// let lock = RwLock::new(42); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 82 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 83 | /// { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 84 | /// let read_guard = lock.read(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 85 | /// assert_eq!(*read_guard, 42); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 86 | /// } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 87 | /// { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 88 | /// let mut write_guard = lock.write(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 89 | /// *write_guard = 100; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 90 | /// } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 91 | /// assert_eq!(*lock.read(), 100); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 92 | /// ``` |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 93 | #[derive(Default, Serialize, Deserialize)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 94 | #[serde(transparent)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 95 | pub struct RwLock<T: ?Sized>(StdRwLock<T>); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 96 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 97 | impl<T> RwLock<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 98 | /// Creates a new `RwLock` wrapping the given value. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 99 | pub const fn new(t: T) -> Self { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 100 | Self(StdRwLock::new(t)) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 101 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 102 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 103 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 104 | impl<T: ?Sized> RwLock<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 105 | /// Acquires a mutable write lock, panicking if the lock is poisoned. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 106 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 107 | /// This method blocks the current thread until the lock is acquired. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 108 | pub fn write(&self) -> RwLockWriteGuard<'_, T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 109 | self.0.write().expect("The RwLock should never be poisoned") |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 110 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 111 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 112 | /// Acquires a shared read lock, panicking if the lock is poisoned. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 113 | /// |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 114 | /// This method blocks the current thread until the lock is acquired. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 115 | pub fn read(&self) -> RwLockReadGuard<'_, T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 116 | self.0.read().expect("The RwLock should never be poisoned") |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 117 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 118 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 119 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 120 | impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 121 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 122 | self.0.fmt(f) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 123 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 124 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 125 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 126 | impl<T> From<T> for RwLock<T> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 127 | fn from(value: T) -> Self { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 128 | Self::new(value) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 129 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 130 | } |