Skip to content

Adds Shared<T> a wrapper for sharing data between handlers #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
)]
#![no_std]

use core::cell::UnsafeCell;
use core::cell::{RefCell, UnsafeCell};

/// A peripheral
#[derive(Debug)]
Expand Down Expand Up @@ -123,3 +123,57 @@ pub unsafe trait Nr {
// to prevent sending non-Sendable stuff (e.g. access tokens) across different
// execution contexts (e.g. interrupts)
unsafe impl<T> Sync for Mutex<T> where T: Send {}

/// A shared value wrapper
///
/// Uses `Mutex` internally, so the same caveats about multi-core systems apply
pub struct Shared<T> {
inner: Mutex<RefCell<Option<T>>>,
}

impl<T> Shared<T> {
/// Creates a new empty shared value
#[cfg(feature = "const-fn")]
pub const fn new() -> Self {
Shared {
inner: Mutex::new(RefCell::new(None)),
}
}

/// Creates a new empty shared value
#[cfg(not(feature = "const-fn"))]
pub fn new() -> Self {
Shared {
inner: Mutex::new(RefCell::new(None)),
}
}

/// Loads new contents into a shared value, if the value already contained
/// data the old value is returned
pub fn put(&self, cs: &CriticalSection, value: T) -> Option<T> {
self.inner.borrow(cs).replace(Some(value))
}

/// Attempts to get a reference to the data in the shared value, may fail
/// if there are current mutable references, or if the value is empty
pub fn get<'a>(&'a self, cs: &'a CriticalSection) -> Option<core::cell::Ref<'a, T>> {
self.inner
.borrow(cs)
.try_borrow()
.ok()
.filter(|inner| inner.is_some())
.map(|inner| core::cell::Ref::map(inner, |v| v.as_ref().unwrap()))
}

/// Attempts to get a reference to the data in the shared value, may fail
/// if there are current mutable or immutable references, or if the value
/// is empty
pub fn get_mut<'a>(&'a self, cs: &'a CriticalSection) -> Option<core::cell::RefMut<'a, T>> {
self.inner
.borrow(cs)
.try_borrow_mut()
.ok()
.filter(|inner| inner.is_some())
.map(|inner| core::cell::RefMut::map(inner, |v| v.as_mut().unwrap()))
}
}