diff options
| author | Alix ANNERAUD <[email protected]> | 2025-04-12 12:26:48 +0200 |
|---|---|---|
| committer | Alix ANNERAUD <[email protected]> | 2025-04-12 12:26:48 +0200 |
| commit | 181a324b4d6ea79a570f020941f0419fbb4530fc (patch) | |
| tree | d3ab85d483949bef612787ec9c86b8e8f0f981e6 /embassy-sync/src | |
| parent | bce15cc813f0fec7eaac1cb709706fb0f4c5e3b8 (diff) | |
Refactor RwLock implementation by removing unused map methods and cleaning up code for improved readability
Diffstat (limited to 'embassy-sync/src')
| -rw-r--r-- | embassy-sync/src/rwlock.rs | 238 |
1 files changed, 1 insertions, 237 deletions
diff --git a/embassy-sync/src/rwlock.rs b/embassy-sync/src/rwlock.rs index 25c575925..deeadd167 100644 --- a/embassy-sync/src/rwlock.rs +++ b/embassy-sync/src/rwlock.rs | |||
| @@ -2,10 +2,10 @@ | |||
| 2 | //! | 2 | //! |
| 3 | //! This module provides a read-write lock that can be used to synchronize data between asynchronous tasks. | 3 | //! This module provides a read-write lock that can be used to synchronize data between asynchronous tasks. |
| 4 | use core::cell::{RefCell, UnsafeCell}; | 4 | use core::cell::{RefCell, UnsafeCell}; |
| 5 | use core::fmt; | ||
| 5 | use core::future::{poll_fn, Future}; | 6 | use core::future::{poll_fn, Future}; |
| 6 | use core::ops::{Deref, DerefMut}; | 7 | use core::ops::{Deref, DerefMut}; |
| 7 | use core::task::Poll; | 8 | use core::task::Poll; |
| 8 | use core::{fmt, mem}; | ||
| 9 | 9 | ||
| 10 | use crate::blocking_mutex::raw::RawMutex; | 10 | use crate::blocking_mutex::raw::RawMutex; |
| 11 | use crate::blocking_mutex::Mutex as BlockingMutex; | 11 | use crate::blocking_mutex::Mutex as BlockingMutex; |
| @@ -221,27 +221,6 @@ where | |||
| 221 | rwlock: &'a RwLock<R, T>, | 221 | rwlock: &'a RwLock<R, T>, |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | impl<'a, M, T> RwLockReadGuard<'a, M, T> | ||
| 225 | where | ||
| 226 | M: RawMutex, | ||
| 227 | T: ?Sized, | ||
| 228 | { | ||
| 229 | /// Map the contents of the `RwLockReadGuard` to a different type. | ||
| 230 | /// | ||
| 231 | /// This is useful for calling methods on the contents of the `RwLockReadGuard` without | ||
| 232 | /// moving out of the guard. | ||
| 233 | pub fn map<U>(this: Self, fun: impl FnOnce(&T) -> &U) -> MappedRwLockReadGuard<'a, M, U> { | ||
| 234 | let rwlock = this.rwlock; | ||
| 235 | let value = fun(unsafe { &mut *this.rwlock.inner.get() }); | ||
| 236 | |||
| 237 | mem::forget(this); | ||
| 238 | MappedRwLockReadGuard { | ||
| 239 | state: &rwlock.state, | ||
| 240 | value, | ||
| 241 | } | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | impl<'a, M, T> Drop for RwLockReadGuard<'a, M, T> | 224 | impl<'a, M, T> Drop for RwLockReadGuard<'a, M, T> |
| 246 | where | 225 | where |
| 247 | M: RawMutex, | 226 | M: RawMutex, |
| @@ -307,25 +286,6 @@ where | |||
| 307 | rwlock: &'a RwLock<R, T>, | 286 | rwlock: &'a RwLock<R, T>, |
| 308 | } | 287 | } |
| 309 | 288 | ||
| 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 | |||
| 329 | impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T> | 289 | impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T> |
| 330 | where | 290 | where |
| 331 | R: RawMutex, | 291 | R: RawMutex, |
| @@ -385,202 +345,6 @@ where | |||
| 385 | } | 345 | } |
| 386 | } | 346 | } |
| 387 | 347 | ||
| 388 | /// A handle to a held `RwLock` that has had a function applied to it via [`RwLockReadGuard::map`] or | ||
| 389 | /// [`MappedRwLockReadGuard::map`]. | ||
| 390 | /// | ||
| 391 | /// This can be used to hold a subfield of the protected data. | ||
| 392 | #[clippy::has_significant_drop] | ||
| 393 | pub struct MappedRwLockReadGuard<'a, M, T> | ||
| 394 | where | ||
| 395 | M: RawMutex, | ||
| 396 | T: ?Sized, | ||
| 397 | { | ||
| 398 | state: &'a BlockingMutex<M, RefCell<State>>, | ||
| 399 | value: *const T, | ||
| 400 | } | ||
| 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 | |||
| 418 | impl<'a, M, T> Deref for MappedRwLockReadGuard<'a, M, T> | ||
| 419 | where | ||
| 420 | M: RawMutex, | ||
| 421 | T: ?Sized, | ||
| 422 | { | ||
| 423 | type Target = T; | ||
| 424 | fn deref(&self) -> &Self::Target { | ||
| 425 | // Safety: the MappedRwLockReadGuard represents shared access to the contents | ||
| 426 | // of the read-write lock, so it's OK to get it. | ||
| 427 | unsafe { &*self.value } | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | impl<'a, M, T> Drop for MappedRwLockReadGuard<'a, M, T> | ||
| 432 | where | ||
| 433 | M: RawMutex, | ||
| 434 | T: ?Sized, | ||
| 435 | { | ||
| 436 | fn drop(&mut self) { | ||
| 437 | self.state.lock(|s| { | ||
| 438 | let mut s = unwrap!(s.try_borrow_mut()); | ||
| 439 | s.readers -= 1; | ||
| 440 | if s.readers == 0 { | ||
| 441 | s.waker.wake(); | ||
| 442 | } | ||
| 443 | }) | ||
| 444 | } | ||
| 445 | } | ||
| 446 | |||
| 447 | unsafe impl<'a, M, T> Send for MappedRwLockReadGuard<'a, M, T> | ||
| 448 | where | ||
| 449 | M: RawMutex, | ||
| 450 | T: ?Sized, | ||
| 451 | { | ||
| 452 | } | ||
| 453 | |||
| 454 | unsafe impl<'a, M, T> Sync for MappedRwLockReadGuard<'a, M, T> | ||
| 455 | where | ||
| 456 | M: RawMutex, | ||
| 457 | T: ?Sized, | ||
| 458 | { | ||
| 459 | } | ||
| 460 | |||
| 461 | impl<'a, M, T> fmt::Debug for MappedRwLockReadGuard<'a, M, T> | ||
| 462 | where | ||
| 463 | M: RawMutex, | ||
| 464 | T: ?Sized + fmt::Debug, | ||
| 465 | { | ||
| 466 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 467 | fmt::Debug::fmt(&**self, f) | ||
| 468 | } | ||
| 469 | } | ||
| 470 | |||
| 471 | impl<'a, M, T> fmt::Display for MappedRwLockReadGuard<'a, M, T> | ||
| 472 | where | ||
| 473 | M: RawMutex, | ||
| 474 | T: ?Sized + fmt::Display, | ||
| 475 | { | ||
| 476 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 477 | fmt::Display::fmt(&**self, f) | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | /// A handle to a held `RwLock` that has had a function applied to it via [`RwLockWriteGuard::map`] or | ||
| 482 | /// [`MappedRwLockWriteGuard::map`]. | ||
| 483 | /// | ||
| 484 | /// This can be used to hold a subfield of the protected data. | ||
| 485 | #[clippy::has_significant_drop] | ||
| 486 | pub struct MappedRwLockWriteGuard<'a, M, T> | ||
| 487 | where | ||
| 488 | M: RawMutex, | ||
| 489 | T: ?Sized, | ||
| 490 | { | ||
| 491 | state: &'a BlockingMutex<M, RefCell<State>>, | ||
| 492 | value: *mut T, | ||
| 493 | } | ||
| 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 | |||
| 511 | impl<'a, M, T> Deref for MappedRwLockWriteGuard<'a, M, T> | ||
| 512 | where | ||
| 513 | M: RawMutex, | ||
| 514 | T: ?Sized, | ||
| 515 | { | ||
| 516 | type Target = T; | ||
| 517 | fn deref(&self) -> &Self::Target { | ||
| 518 | // Safety: the MappedRwLockWriteGuard represents exclusive access to the contents | ||
| 519 | // of the read-write lock, so it's OK to get it. | ||
| 520 | unsafe { &*self.value } | ||
| 521 | } | ||
| 522 | } | ||
| 523 | |||
| 524 | impl<'a, M, T> DerefMut for MappedRwLockWriteGuard<'a, M, T> | ||
| 525 | where | ||
| 526 | M: RawMutex, | ||
| 527 | T: ?Sized, | ||
| 528 | { | ||
| 529 | fn deref_mut(&mut self) -> &mut Self::Target { | ||
| 530 | // Safety: the MappedRwLockWriteGuard represents exclusive access to the contents | ||
| 531 | // of the read-write lock, so it's OK to get it. | ||
| 532 | unsafe { &mut *self.value } | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | impl<'a, M, T> Drop for MappedRwLockWriteGuard<'a, M, T> | ||
| 537 | where | ||
| 538 | M: RawMutex, | ||
| 539 | T: ?Sized, | ||
| 540 | { | ||
| 541 | fn drop(&mut self) { | ||
| 542 | self.state.lock(|s| { | ||
| 543 | let mut s = unwrap!(s.try_borrow_mut()); | ||
| 544 | s.writer = false; | ||
| 545 | s.waker.wake(); | ||
| 546 | }) | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 550 | unsafe impl<'a, M, T> Send for MappedRwLockWriteGuard<'a, M, T> | ||
| 551 | where | ||
| 552 | M: RawMutex, | ||
| 553 | T: ?Sized, | ||
| 554 | { | ||
| 555 | } | ||
| 556 | |||
| 557 | unsafe impl<'a, M, T> Sync for MappedRwLockWriteGuard<'a, M, T> | ||
| 558 | where | ||
| 559 | M: RawMutex, | ||
| 560 | T: ?Sized, | ||
| 561 | { | ||
| 562 | } | ||
| 563 | |||
| 564 | impl<'a, M, T> fmt::Debug for MappedRwLockWriteGuard<'a, M, T> | ||
| 565 | where | ||
| 566 | M: RawMutex, | ||
| 567 | T: ?Sized + fmt::Debug, | ||
| 568 | { | ||
| 569 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 570 | fmt::Debug::fmt(&**self, f) | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | impl<'a, M, T> fmt::Display for MappedRwLockWriteGuard<'a, M, T> | ||
| 575 | where | ||
| 576 | M: RawMutex, | ||
| 577 | T: ?Sized + fmt::Display, | ||
| 578 | { | ||
| 579 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 580 | fmt::Display::fmt(&**self, f) | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | #[cfg(test)] | 348 | #[cfg(test)] |
| 585 | mod tests { | 349 | mod tests { |
| 586 | use crate::blocking_mutex::raw::NoopRawMutex; | 350 | use crate::blocking_mutex::raw::NoopRawMutex; |
