diff --git a/codes/pin/Cargo.lock b/codes/pin/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..9c107afa741b78a2495f1c4ff0b2c51c51dc885d --- /dev/null +++ b/codes/pin/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "pin" +version = "0.1.0" diff --git a/codes/pin/Cargo.toml b/codes/pin/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f312b79f7dde13834a69d3f33fdc90c6c83b394e --- /dev/null +++ b/codes/pin/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "pin" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/codes/pin/src/main.rs b/codes/pin/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..640ce55c1e2fee350e880403dd671c633694f841 --- /dev/null +++ b/codes/pin/src/main.rs @@ -0,0 +1,87 @@ +use std::marker::PhantomPinned; +use std::mem::swap; +use std::pin::{Pin, pin}; +use std::usize; + +struct MaybeSelfRef { + data: usize, + self_ref: Option<*mut usize>, + _pin: PhantomPinned, +} + +impl MaybeSelfRef { + // when creating a new MaybeSelfRef instance there is no self reference. We start with default + // values. + fn new() -> Self { + Self { + data: 0, + self_ref: None, + _pin: PhantomPinned::default(), + } + } + fn init(self: Pin<&mut Self>) { + unsafe { + let Self { data, self_ref, .. } = self.get_unchecked_mut(); + *self_ref = Some(data); + } + } + fn self_ref(self: Pin<&mut Self>) -> Option<&mut usize> { + unsafe { self.get_unchecked_mut().self_ref.map(|sr| &mut *sr) } + } +} + +fn main() { + let mut x = Box::pin(MaybeSelfRef::new()); + x.as_mut().init(); + println!("Heap Pinning data {}", x.as_ref().data); + *x.as_mut().self_ref().unwrap() = 10; + println!("Heap Pinning modified {}", x.as_ref().data); + + let mut x = MaybeSelfRef::new(); + let mut x = unsafe { Pin::new_unchecked(&mut x) }; + x.as_mut().init(); + println!(" Pinning data {}", x.as_ref().data); + *x.as_mut().self_ref().unwrap() = 10; + println!("Heap Pinning modified {}", x.as_ref().data); + + println!("Problem with Stack pinning"); + let mut x = MaybeSelfRef::new(); + let mut y = MaybeSelfRef::new(); + { + unsafe { + let mut x = Pin::new_unchecked(&mut x); + x.as_mut().init(); + *x.as_mut().self_ref().unwrap() = 10; + }; + } + swap(&mut x, &mut y); + println!( + " +x: {{ + +----->a: {:p}, + | b: {:?}, + | }} + | + | y: {{ + | a: {:p}, + +-----|b: {:?}, + }}", + &x.data, x.self_ref, &y.data, y.self_ref, + ); + + println!("Problem with Stack pinning the pin! macro to the rescue"); + let mut x = pin!(MaybeSelfRef::new()); + //let mut y = pin!(MaybeSelfRef::new()); + //{ + // unsafe { + // let mut x = Pin::new_unchecked(&mut x); + // x.as_mut().init(); + // *x.as_mut().self_ref().unwrap() = 10; + // }; + //} + //swap(&mut x, &mut y); + MaybeSelfRef::init(x.as_mut()); + println!("Pinning with pin! {}", x.as_ref().data); + *x.as_mut().self_ref().unwrap() = 12; + println!("Pinning with pin! after modification {}", x.as_ref().data); +}