diff options
Diffstat (limited to 'embassy-sync/src/rwlock.rs')
| -rw-r--r-- | embassy-sync/src/rwlock.rs | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/embassy-sync/src/rwlock.rs b/embassy-sync/src/rwlock.rs index 7f0bbec60..25c575925 100644 --- a/embassy-sync/src/rwlock.rs +++ b/embassy-sync/src/rwlock.rs | |||
| @@ -11,7 +11,7 @@ use crate::blocking_mutex::raw::RawMutex; | |||
| 11 | use crate::blocking_mutex::Mutex as BlockingMutex; | 11 | use crate::blocking_mutex::Mutex as BlockingMutex; |
| 12 | use crate::waitqueue::WakerRegistration; | 12 | use crate::waitqueue::WakerRegistration; |
| 13 | 13 | ||
| 14 | /// Error returned by [`RwLock::try_read_lock`] and [`RwLock::try_write_lock`] | 14 | /// Error returned by [`RwLock::try_read`] and [`RwLock::try_write`] when the lock is already held. |
| 15 | #[derive(PartialEq, Eq, Clone, Copy, Debug)] | 15 | #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
| 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 17 | pub struct TryLockError; | 17 | pub struct TryLockError; |
| @@ -24,7 +24,7 @@ struct State { | |||
| 24 | 24 | ||
| 25 | /// Async read-write lock. | 25 | /// Async read-write lock. |
| 26 | /// | 26 | /// |
| 27 | /// The read-write lock is generic over a blocking [`RawRwLock`](crate::blocking_mutex::raw_rwlock::RawRwLock). | 27 | /// The read-write lock is generic over the raw mutex implementation `M` and the data `T` it protects. |
| 28 | /// The raw read-write lock is used to guard access to the internal state. It | 28 | /// The raw read-write lock is used to guard access to the internal state. It |
| 29 | /// is held for very short periods only, while locking and unlocking. It is *not* held | 29 | /// is held for very short periods only, while locking and unlocking. It is *not* held |
| 30 | /// for the entire time the async RwLock is locked. | 30 | /// for the entire time the async RwLock is locked. |
| @@ -307,6 +307,25 @@ where | |||
| 307 | rwlock: &'a RwLock<R, T>, | 307 | rwlock: &'a RwLock<R, T>, |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | impl<'a, R, T> RwLockWriteGuard<'a, R, T> | ||
| 311 | where | ||
| 312 | R: RawMutex, | ||
| 313 | T: ?Sized, | ||
| 314 | { | ||
| 315 | /// Returns a locked view over a portion of the locked data. | ||
| 316 | pub fn map<U>(this: Self, fun: impl FnOnce(&mut T) -> &mut U) -> MappedRwLockWriteGuard<'a, R, U> { | ||
| 317 | let rwlock = this.rwlock; | ||
| 318 | let value = fun(unsafe { &mut *this.rwlock.inner.get() }); | ||
| 319 | // Dont run the `drop` method for RwLockWriteGuard. The ownership of the underlying | ||
| 320 | // locked state is being moved to the returned MappedRwLockWriteGuard. | ||
| 321 | mem::forget(this); | ||
| 322 | MappedRwLockWriteGuard { | ||
| 323 | state: &rwlock.state, | ||
| 324 | value, | ||
| 325 | } | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 310 | impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T> | 329 | impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T> |
| 311 | where | 330 | where |
| 312 | R: RawMutex, | 331 | R: RawMutex, |
| @@ -366,8 +385,8 @@ where | |||
| 366 | } | 385 | } |
| 367 | } | 386 | } |
| 368 | 387 | ||
| 369 | /// A handle to a held `Mutex` that has had a function applied to it via [`MutexGuard::map`] or | 388 | /// A handle to a held `RwLock` that has had a function applied to it via [`RwLockReadGuard::map`] or |
| 370 | /// [`MappedMutexGuard::map`]. | 389 | /// [`MappedRwLockReadGuard::map`]. |
| 371 | /// | 390 | /// |
| 372 | /// This can be used to hold a subfield of the protected data. | 391 | /// This can be used to hold a subfield of the protected data. |
| 373 | #[clippy::has_significant_drop] | 392 | #[clippy::has_significant_drop] |
| @@ -380,6 +399,22 @@ where | |||
| 380 | value: *const T, | 399 | value: *const T, |
| 381 | } | 400 | } |
| 382 | 401 | ||
| 402 | impl<'a, M, T> MappedRwLockReadGuard<'a, M, T> | ||
| 403 | where | ||
| 404 | M: RawMutex, | ||
| 405 | T: ?Sized, | ||
| 406 | { | ||
| 407 | /// Returns a locked view over a portion of the locked data. | ||
| 408 | pub fn map<U>(this: Self, fun: impl FnOnce(&T) -> &U) -> MappedRwLockReadGuard<'a, M, U> { | ||
| 409 | let rwlock = this.state; | ||
| 410 | let value = fun(unsafe { &*this.value }); | ||
| 411 | // Dont run the `drop` method for RwLockReadGuard. The ownership of the underlying | ||
| 412 | // locked state is being moved to the returned MappedRwLockReadGuard. | ||
| 413 | mem::forget(this); | ||
| 414 | MappedRwLockReadGuard { state: rwlock, value } | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 383 | impl<'a, M, T> Deref for MappedRwLockReadGuard<'a, M, T> | 418 | impl<'a, M, T> Deref for MappedRwLockReadGuard<'a, M, T> |
| 384 | where | 419 | where |
| 385 | M: RawMutex, | 420 | M: RawMutex, |
| @@ -443,8 +478,8 @@ where | |||
| 443 | } | 478 | } |
| 444 | } | 479 | } |
| 445 | 480 | ||
| 446 | /// A handle to a held `Mutex` that has had a function applied to it via [`MutexGuard::map`] or | 481 | /// A handle to a held `RwLock` that has had a function applied to it via [`RwLockWriteGuard::map`] or |
| 447 | /// [`MappedMutexGuard::map`]. | 482 | /// [`MappedRwLockWriteGuard::map`]. |
| 448 | /// | 483 | /// |
| 449 | /// This can be used to hold a subfield of the protected data. | 484 | /// This can be used to hold a subfield of the protected data. |
| 450 | #[clippy::has_significant_drop] | 485 | #[clippy::has_significant_drop] |
| @@ -457,6 +492,22 @@ where | |||
| 457 | value: *mut T, | 492 | value: *mut T, |
| 458 | } | 493 | } |
| 459 | 494 | ||
| 495 | impl<'a, M, T> MappedRwLockWriteGuard<'a, M, T> | ||
| 496 | where | ||
| 497 | M: RawMutex, | ||
| 498 | T: ?Sized, | ||
| 499 | { | ||
| 500 | /// Returns a locked view over a portion of the locked data. | ||
| 501 | pub fn map<U>(this: Self, fun: impl FnOnce(&mut T) -> &mut U) -> MappedRwLockWriteGuard<'a, M, U> { | ||
| 502 | let rwlock = this.state; | ||
| 503 | let value = fun(unsafe { &mut *this.value }); | ||
| 504 | // Dont run the `drop` method for RwLockWriteGuard. The ownership of the underlying | ||
| 505 | // locked state is being moved to the returned MappedRwLockWriteGuard. | ||
| 506 | mem::forget(this); | ||
| 507 | MappedRwLockWriteGuard { state: rwlock, value } | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 460 | impl<'a, M, T> Deref for MappedRwLockWriteGuard<'a, M, T> | 511 | impl<'a, M, T> Deref for MappedRwLockWriteGuard<'a, M, T> |
| 461 | where | 512 | where |
| 462 | M: RawMutex, | 513 | M: RawMutex, |
