aboutsummaryrefslogtreecommitdiff
path: root/embassy-sync/src
diff options
context:
space:
mode:
authorAlix ANNERAUD <[email protected]>2025-04-12 12:26:48 +0200
committerAlix ANNERAUD <[email protected]>2025-04-12 12:26:48 +0200
commit181a324b4d6ea79a570f020941f0419fbb4530fc (patch)
treed3ab85d483949bef612787ec9c86b8e8f0f981e6 /embassy-sync/src
parentbce15cc813f0fec7eaac1cb709706fb0f4c5e3b8 (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.rs238
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.
4use core::cell::{RefCell, UnsafeCell}; 4use core::cell::{RefCell, UnsafeCell};
5use core::fmt;
5use core::future::{poll_fn, Future}; 6use core::future::{poll_fn, Future};
6use core::ops::{Deref, DerefMut}; 7use core::ops::{Deref, DerefMut};
7use core::task::Poll; 8use core::task::Poll;
8use core::{fmt, mem};
9 9
10use crate::blocking_mutex::raw::RawMutex; 10use crate::blocking_mutex::raw::RawMutex;
11use crate::blocking_mutex::Mutex as BlockingMutex; 11use 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
224impl<'a, M, T> RwLockReadGuard<'a, M, T>
225where
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
245impl<'a, M, T> Drop for RwLockReadGuard<'a, M, T> 224impl<'a, M, T> Drop for RwLockReadGuard<'a, M, T>
246where 225where
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
310impl<'a, R, T> RwLockWriteGuard<'a, R, T>
311where
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
329impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T> 289impl<'a, R, T> Drop for RwLockWriteGuard<'a, R, T>
330where 290where
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]
393pub struct MappedRwLockReadGuard<'a, M, T>
394where
395 M: RawMutex,
396 T: ?Sized,
397{
398 state: &'a BlockingMutex<M, RefCell<State>>,
399 value: *const T,
400}
401
402impl<'a, M, T> MappedRwLockReadGuard<'a, M, T>
403where
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
418impl<'a, M, T> Deref for MappedRwLockReadGuard<'a, M, T>
419where
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
431impl<'a, M, T> Drop for MappedRwLockReadGuard<'a, M, T>
432where
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
447unsafe impl<'a, M, T> Send for MappedRwLockReadGuard<'a, M, T>
448where
449 M: RawMutex,
450 T: ?Sized,
451{
452}
453
454unsafe impl<'a, M, T> Sync for MappedRwLockReadGuard<'a, M, T>
455where
456 M: RawMutex,
457 T: ?Sized,
458{
459}
460
461impl<'a, M, T> fmt::Debug for MappedRwLockReadGuard<'a, M, T>
462where
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
471impl<'a, M, T> fmt::Display for MappedRwLockReadGuard<'a, M, T>
472where
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]
486pub struct MappedRwLockWriteGuard<'a, M, T>
487where
488 M: RawMutex,
489 T: ?Sized,
490{
491 state: &'a BlockingMutex<M, RefCell<State>>,
492 value: *mut T,
493}
494
495impl<'a, M, T> MappedRwLockWriteGuard<'a, M, T>
496where
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
511impl<'a, M, T> Deref for MappedRwLockWriteGuard<'a, M, T>
512where
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
524impl<'a, M, T> DerefMut for MappedRwLockWriteGuard<'a, M, T>
525where
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
536impl<'a, M, T> Drop for MappedRwLockWriteGuard<'a, M, T>
537where
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
550unsafe impl<'a, M, T> Send for MappedRwLockWriteGuard<'a, M, T>
551where
552 M: RawMutex,
553 T: ?Sized,
554{
555}
556
557unsafe impl<'a, M, T> Sync for MappedRwLockWriteGuard<'a, M, T>
558where
559 M: RawMutex,
560 T: ?Sized,
561{
562}
563
564impl<'a, M, T> fmt::Debug for MappedRwLockWriteGuard<'a, M, T>
565where
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
574impl<'a, M, T> fmt::Display for MappedRwLockWriteGuard<'a, M, T>
575where
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)]
585mod tests { 349mod tests {
586 use crate::blocking_mutex::raw::NoopRawMutex; 350 use crate::blocking_mutex::raw::NoopRawMutex;