Skip to content

Commit 4c8a45b

Browse files
committed
zephyr: sync: Create PinWeak type
The pin-weak provides a weak pointer that is compatible with `Pin<Arc>`. Unfortunately, these are not compatible with the Arc that we use from portable-atomic-utils. Provide a simplified implementation of this until the pin-weak is able to gain this functionality. Signed-off-by: David Brown <[email protected]>
1 parent 05bb60e commit 4c8a45b

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

zephyr/src/sync.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,41 @@ pub mod atomic {
2525
pub use portable_atomic::*;
2626
}
2727

28+
use core::pin::Pin;
29+
2830
#[cfg(CONFIG_RUST_ALLOC)]
2931
pub use portable_atomic_util::Arc;
3032
#[cfg(CONFIG_RUST_ALLOC)]
3133
pub use portable_atomic_util::Weak;
3234

35+
/// Safe Pinned Weak references.
36+
///
37+
/// Pin<Arc<T>> can't be converted to/from Weak safely, because there is know way to know if a given
38+
/// weak reference came from a pinned Arc. This wraps the weak reference in a new type so we know
39+
/// that it came from a pinned Arc.
40+
///
41+
/// There is a pin-weak crate that provides this for `std::sync::Arc`, but not for the one in the
42+
/// portable-atomic-utils crate.
43+
pub struct PinWeak<T>(Weak<T>);
44+
45+
impl<T> PinWeak<T> {
46+
/// Downgrade an `Pin<Arc<T>>` into a `PinWeak`.
47+
///
48+
/// This would be easier to use if it could be added to Arc.
49+
pub fn downgrade(this: Pin<Arc<T>>) -> Self {
50+
// SAFETY: we will never return anything other than a Pin<Arc<T>>.
51+
Self(Arc::downgrade(&unsafe { Pin::into_inner_unchecked(this) }))
52+
}
53+
54+
/// Upgrade back to a `Pin<Arc<T>>`.
55+
pub fn upgrade(&self) -> Option<Pin<Arc<T>>> {
56+
// SAFETY: The weak was only constructed from a `Pin<Arc<T>>`.
57+
self.0
58+
.upgrade()
59+
.map(|arc| unsafe { Pin::new_unchecked(arc) })
60+
}
61+
}
62+
3363
mod mutex;
3464

3565
pub use mutex::{Condvar, LockResult, Mutex, MutexGuard, TryLockError, TryLockResult};

0 commit comments

Comments
 (0)