### ArcShift Usage Example Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShift.html?search= Basic initialization and retrieval of a value stored in an ArcShift instance. ```rust let mut instance = ArcShift::new("test"); println!("Value: {:?}", instance.get()); ``` -------------------------------- ### Reload the ArcShiftCell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Triggers a reload to drop heap blocks no longer needed. This method is a no-op if called during a get closure. ```rust pub fn reload(&self) { if self.recursion.get() == 0 { // SAFETY: // For 'reload' to be safe, we must be sure that no other execution has a reference // to 'self.item', since the value it points to might be dropped. // This guarantee is fulfilled, because there is no way to get such a reference // other than receiving it in the callback given to 'get'. And for as long as the // callback is executing, 'recursion' will be != 0. unsafe { &mut *self.inner.get() }.reload() } } ``` -------------------------------- ### Access the inner value with get Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Provides reentrant access to the inner value via a closure. Only the outermost invocation triggers a reload. ```rust #[inline] pub fn get(&self, f: impl FnOnce(&T) -> R) -> R { self.recursion.set(self.recursion.get() + 1); let val = if self.recursion.get() == 1 { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now unsafe { &mut *self.inner.get() }.get() } else { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now unsafe { &*self.inner.get() }.shared_non_reloading_get() }; let t = f(val); self.recursion.set(self.recursion.get() - 1); t } ``` -------------------------------- ### Using ArcShift for Thread-Safe Data Sharing Source: https://docs.rs/arcshift/0.4.4/arcshift/index.html?search= Demonstrates initializing an ArcShift instance, cloning it for use across threads, and performing read and update operations. ```rust use std::thread; let mut arc = ArcShift::new("Hello".to_string()); let mut arc2 = arc.clone(); let j1 = thread::spawn(move||{ println!("Value in thread 1: '{}'", arc.get()); //Prints 'Hello' arc.update("New value".to_string()); println!("Updated value in thread 1: '{}'", arc.get()); //Prints 'New value' }); let j2 = thread::spawn(move||{ // Prints either 'Hello' or 'New value', depending on scheduling: println!("Value in thread 2: '{}'", arc2.get()); }); j1.join().unwrap(); j2.join().unwrap(); ``` -------------------------------- ### Create New ArcShiftCell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Constructor methods for initializing an ArcShiftCell. ```rust impl ArcShiftCell { /// Create a new ArcShiftCell with the given value. pub fn new(value: T) -> ArcShiftCell { ArcShiftCell::from_arcshift(ArcShift::new(value)) } } impl ArcShiftCell { /// Creates an ArcShiftCell from an ArcShift-instance. ``` -------------------------------- ### Implementing ArcShift for Hot-Reloading Assets Source: https://docs.rs/arcshift/0.4.4/arcshift/index.html?search= Demonstrates using ArcShift to manage a collection of character models that can be updated dynamically from a background thread while being accessed by the main game loop. ```rust struct CharacterModel { /* 3D model, textures, etc*/ } struct World { models: Vec> } /// Loads models. Regularly scans filesystem, /// updates models when their files change on disk. fn load_models() -> Vec> { let models: Vec> = vec![]; /* Somehow load models */ let mut models_for_reloader = models.clone(); std::thread::spawn(move||{ loop { /* detect file system changes*/ let changed_model = 0usize; models_for_reloader[changed_model].update(CharacterModel{/* newly loaded*/}); } }); models } fn run_game() { let mut world = World { models: load_models() }; loop { run_game_logic(&mut world); } } fn run_game_logic(world: &mut World) { /* Do game logic, possibly in multiple threads, accessing different parts of World, possibly cloning 'ArcShift' instances for use by other threads */ for model in world.models.iter_mut() { // Accessing ArcShift using 'get' ensures // old versions do not linger in RAM. let model_ref : &CharacterModel = model.get(); // Do stuff with 'model_ref' } } ``` -------------------------------- ### ArcShiftCell Implementation Methods Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Methods for creating, borrowing, and managing the state of an ArcShiftCell. ```rust pub fn new(value: T) -> ArcShiftCell ``` ```rust pub fn from_arcshift(input: ArcShift) -> ArcShiftCell ``` ```rust pub fn borrow(&self) -> ArcShiftCellHandle<'_, T> ``` ```rust pub fn get(&self, f: impl FnOnce(&T) -> R) -> R ``` ```rust pub fn assign(&self, other: &ArcShift) -> Result<(), RecursionDetected> ``` ```rust pub fn reload(&self) ``` ```rust pub fn make_arcshift(&self) -> ArcShift ``` -------------------------------- ### pub fn upgrade(&self) -> Option> Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShiftWeak.html?search=std%3A%3Avec Attempts to upgrade the ArcShiftWeak pointer to a full ArcShift instance. Returns Some(ArcShift) if the value still exists, or None if the original ArcShift has been deallocated. ```APIDOC ## pub fn upgrade(&self) -> Option> ### Description Attempts to upgrade this ArcShiftWeak instance to a full ArcShift. This is required to access the stored value. If the original ArcShift instance has been deallocated, this method returns None. ### Returns - **Option>** - An Option containing the upgraded ArcShift if successful, otherwise None. ``` -------------------------------- ### Usage of ArcShiftWeak Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShiftWeak.html?search=u32+-%3E+bool Demonstrates creating a weak reference from an ArcShift instance and upgrading it back to access the value. ```rust let original_instance = ArcShift::new("test"); let light_instance = ArcShift::downgrade(&original_instance); let mut instance = light_instance.upgrade().unwrap(); println!("Value: {:?}", instance.get()); ``` -------------------------------- ### Implement DropHandler for deferred panic management Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper/std_drop_handler.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Defines the DropHandler structure and its implementation of IDropHandler to safely execute drop logic while catching potential panics. ```rust use crate::deferred_panics_helper::IDropHandler; use crate::{debug_println, IMetadata, ItemHolder}; use core::any::Any; use core::marker::PhantomData; use core::mem::ManuallyDrop; /// A drop handler that will persist the most recent panic, allowing it /// to be unwinded later pub(crate) struct DropHandler { panic: Option>, phantom: PhantomData<*mut T>, } impl Default for DropHandler { fn default() -> Self { Self { panic: None, phantom: Default::default(), } } } impl IDropHandler for DropHandler { fn do_drop(&mut self, item_ptr: *mut ItemHolder) { self.run(|| { // SAFETY: item_ptr must be valid, guaranteed by caller. let payload = unsafe { &(*item_ptr).payload }; debug_println!("payload ref created (std drop)"); // SAFETY: item_ptr is now uniquely owned. We can drop it. unsafe { ManuallyDrop::drop(&mut *payload.get()) }; debug_println!("payload dropped"); }) } fn report_sole_user(&mut self) {} } impl DropHandler { pub(crate) fn do_drop_value(&mut self, value: T) where T: Sized, { self.run(move || { let _ = value; }); } pub(crate) fn run(&mut self, job: impl FnOnce()) { // We do use AssertUnwindSafe here. // Most of the time, this is perfectly fine, since this crate doesn't // care about the internals of the payload type (T), so any inconsistency // left there is fine to this crate. For the user, they won't typically // observe any inconsistency either, since we resume_unwind (re-throw) this panic // before returning to the user. // // There is one exception to this. For example, if multiple objects are dropped in the same // ArcShift-invocation, and the first drop panics, and the second object has a // reference to some third object that the first drop partially updated and left in // an inconsistent state. // // This is deemed acceptable. Alternatives would be : // // * Require that all payload objects implement UnwindSafe. Clearly annoying. // * Don't run subsequent drop-methods if the first panicked. Since leaking is safe, // this is perhaps technically more idiomatic than the chosen solution. However, // Drop-impls should rarely need to update foreign objects, and also, drop-methods // really shouldn't panic at all. match std::panic::catch_unwind(std::panic::AssertUnwindSafe(job)) { Ok(()) => {} Err(err) => { self.panic.get_or_insert(err); } } } pub(crate) fn resume_any_panics(self) { if let Some(panic) = self.panic { std::panic::resume_unwind(panic); } } } ``` -------------------------------- ### Create an ArcShiftCell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Initializes an ArcShiftCell from an existing ArcShift instance without cloning the underlying payload. ```rust pub fn from_arcshift(input: ArcShift) -> ArcShiftCell { ArcShiftCell { inner: UnsafeCell::new(input), recursion: Cell::new(0), } } ``` -------------------------------- ### ArcShiftCell::new Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Creates a new ArcShiftCell instance with the provided value. ```APIDOC ### pub fn new(value: T) -> ArcShiftCell Creates a new ArcShiftCell with the given value. ``` -------------------------------- ### ArcShiftCell Method Implementations Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=u32+-%3E+bool Core methods for managing ArcShiftCell state, including reentrant access and safe updates. ```rust pub fn from_arcshift(input: ArcShift) -> ArcShiftCell { ArcShiftCell { inner: UnsafeCell::new(input), recursion: Cell::new(0), } } ``` ```rust #[inline] pub fn borrow(&self) -> ArcShiftCellHandle<'_, T> { self.recursion.set(self.recursion.get() + 1); ArcShiftCellHandle { cell: self, _marker: PhantomData, } } ``` ```rust #[inline] pub fn get(&self, f: impl FnOnce(&T) -> R) -> R { self.recursion.set(self.recursion.get() + 1); let val = if self.recursion.get() == 1 { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now unsafe { &mut *self.inner.get() }.get() } else { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now unsafe { &*self.inner.get() }.shared_non_reloading_get() }; let t = f(val); self.recursion.set(self.recursion.get() - 1); t } ``` ```rust pub fn assign(&self, other: &ArcShift) -> Result<(), RecursionDetected> { if self.recursion.get() == 0 { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now *unsafe { &mut *self.inner.get() } = other.clone(); Ok(()) } else { Err(RecursionDetected) } } ``` ```rust pub fn reload(&self) { if self.recursion.get() == 0 { // SAFETY: // For 'reload' to be safe, we must be sure that no other execution has a reference // to 'self.item', since the value it points to might be dropped. // This guarantee is fulfilled, because there is no way to get such a reference // other than receiving it in the callback given to 'get'. And for as long as the // callback is executing, 'recursion' will be != 0. unsafe { &mut *self.inner.get() }.reload() } } ``` ```rust pub fn make_arcshift(&self) -> ArcShift { // SAFETY: // ArcShiftCell is not Sync, and 'make_arcshift' does not recursively call into user // code, so we know no other operation can be ongoing. unsafe { &mut *self.inner.get() }.clone() } ``` -------------------------------- ### ArcShift Methods Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShift.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Core methods for creating, updating, and accessing values within an ArcShift instance. ```APIDOC ## ArcShift Methods ### new(val: T) -> ArcShift Creates a new ArcShift instance with the given value. ### try_into_inner(self) -> Option Drops this ArcShift instance. If this was the last instance of the entire chain, the payload value is returned. ### update(&mut self, val: T) Update the value of this ArcShift instance (and all derived from it) to the given value. ### rcu(&mut self, update: impl FnMut(&T) -> T) -> &T Atomically update the value using a closure. Returns a reference to the newly-set value. ### rcu_maybe(&mut self, update: impl FnMut(&T) -> Option) -> bool Atomically update the value. If the closure returns None, the update is canceled and the method returns false. ### from_box(input: Box) -> ArcShift Creates an ArcShift instance from a Box, avoiding stack copies. ### try_get_mut(&mut self) -> Option<&mut T> Returns a mutable reference to the inner value if no other instances exist. ### update_box(&mut self, new_payload: Box) Updates the value using a Box, required for unsized types. ### get(&mut self) -> &T Advances this instance to the most recent value and returns a reference. ### shared_get(&self) -> SharedGetGuard<'_, T> Gets the current value. Note: may incur a performance penalty if the instance is stale. ### shared_non_reloading_get(&self) -> &T Gets the current value without reloading. May return a stale value. ### downgrade(this: &ArcShift) -> ArcShiftWeak Creates a weak reference to the ArcShift instance. ### reload(&mut self) Advances this instance to the most recent value, freeing superseded values. ``` -------------------------------- ### ArcShiftCell Trait Implementations and Constructors Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Provides Send, Clone, and initialization methods for ArcShiftCell. ```rust unsafe impl Send for ArcShiftCell where T: Send + Sync {} impl Clone for ArcShiftCell { fn clone(&self) -> Self { // SAFETY: // Accessing the inner value is safe, since we know no other thread // can be interacting with it. And even if we're in a recursive call to // 'get', we're not mutating the value and cloning it is thus perfectly safe. let clone = unsafe { &mut *self.inner.get() }.clone(); ArcShiftCell { inner: UnsafeCell::new(clone), recursion: Cell::new(0), } } } impl ArcShiftCell { /// Create a new ArcShiftCell with the given value. pub fn new(value: T) -> ArcShiftCell { ArcShiftCell::from_arcshift(ArcShift::new(value)) } } ``` -------------------------------- ### DropHandler Implementation Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper/std_drop_handler.rs.html The DropHandler struct and its associated methods for capturing and resuming panics during drop operations. ```rust 1use crate::deferred_panics_helper::IDropHandler; 2use crate::{debug_println, IMetadata, ItemHolder}; 3use core::any::Any; 4use core::marker::PhantomData; 5use core::mem::ManuallyDrop; 6 7/// A drop handler that will persist the most recent panic, allowing it 8/// to be unwinded later 9pub(crate) struct DropHandler { 10 panic: Option>, 11 phantom: PhantomData<*mut T>, 12} 13 14impl Default for DropHandler { 15 fn default() -> Self { 16 Self { 17 panic: None, 18 phantom: Default::default(), 19 } 20 } 21} 22 23impl IDropHandler for DropHandler { 24 fn do_drop(&mut self, item_ptr: *mut ItemHolder) { 25 self.run(|| { 26 // SAFETY: item_ptr must be valid, guaranteed by caller. 27 let payload = unsafe { &(*item_ptr).payload }; 28 debug_println!("payload ref created (std drop)"); 29 30 // SAFETY: item_ptr is now uniquely owned. We can drop it. 31 unsafe { ManuallyDrop::drop(&mut *payload.get()) }; 32 debug_println!("payload dropped"); 33 }) 34 } 35 36 fn report_sole_user(&mut self) {} 37} 38 39impl DropHandler { 40 pub(crate) fn do_drop_value(&mut self, value: T) 41 where 42 T: Sized, 43 { 44 self.run(move || { 45 let _ = value; 46 }); 47 } 48 pub(crate) fn run(&mut self, job: impl FnOnce()) { 49 // We do use AssertUnwindSafe here. 50 // Most of the time, this is perfectly fine, since this crate doesn't 51 // care about the internals of the payload type (T), so any inconsistency 52 // left there is fine to this crate. For the user, they won't typically 53 // observe any inconsistency either, since we resume_unwind (re-throw) this panic 54 // before returning to the user. 55 // 56 // There is one exception to this. For example, if multiple objects are dropped in the same 57 // ArcShift-invocation, and the first drop panics, and the second object has a 58 // reference to some third object that the first drop partially updated and left in 59 // an inconsistent state. 60 // 61 // This is deemed acceptable. Alternatives would be : 62 // 63 // * Require that all payload objects implement UnwindSafe. Clearly annoying. 64 // * Don't run subsequent drop-methods if the first panicked. Since leaking is safe, 65 // this is perhaps technically more idiomatic than the chosen solution. However, 66 // Drop-impls should rarely need to update foreign objects, and also, drop-methods 67 // really shouldn't panic at all. 68 69 match std::panic::catch_unwind(std::panic::AssertUnwindSafe(job)) { 70 Ok(()) => {} 71 Err(err) => { 72 self.panic.get_or_insert(err); 73 } 74 } 75 } 76 pub(crate) fn resume_any_panics(self) { 77 if let Some(panic) = self.panic { 78 std::panic::resume_unwind(panic); 79 } 80 } 81} ``` -------------------------------- ### Implement Debug for ArcShiftCell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Formats the ArcShiftCell for debugging purposes. ```rust impl Debug for ArcShiftCell where T: Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "ArcShiftCell({:?})", &*self.borrow()) } } ``` -------------------------------- ### Create an ArcShift instance from cell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Creates a new ArcShift instance pointing to the same value as the cell. ```rust pub fn make_arcshift(&self) -> ArcShift { // SAFETY: // ArcShiftCell is not Sync, and 'make_arcshift' does not recursively call into user // code, so we know no other operation can be ongoing. unsafe { &mut *self.inner.get() }.clone() } ``` -------------------------------- ### ArcShiftCell Trait Implementations and Helpers Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=u32+-%3E+bool Implementations for Send, Clone, and error handling for ArcShiftCell. ```rust /// ArcShiftCell cannot be Sync, but there's nothing stopping it from being Send. /// /// Note that ArcShiftCell *cannot* be Sync, because then multiple threads /// could call 'get' simultaneously, corrupting the (non-atomic) refcount. // SAFETY: // As long as the contents of the cell are not !Send, it is safe to // send the cell. The object must be uniquely owned to be sent, and // this is only possible if we're not in a recursive call to // 'get'. And in this case, the properties of ArcShiftCell are the same // as ArcShift, and ArcShift is Send (if T is Send + Sync). // unsafe impl Send for ArcShiftCell where T: Send + Sync {} impl Clone for ArcShiftCell { fn clone(&self) -> Self { // SAFETY: // Accessing the inner value is safe, since we know no other thread // can be interacting with it. And even if we're in a recursive call to // 'get', we're not mutating the value and cloning it is thus perfectly safe. let clone = unsafe { &mut *self.inner.get() }.clone(); ArcShiftCell { inner: UnsafeCell::new(clone), recursion: Cell::new(0), } } } /// Error type representing the case that an operation was attempted from within /// a 'get'-method closure. pub struct RecursionDetected; impl Debug for RecursionDetected { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "RecursionDetected") } } impl Display for RecursionDetected { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "RecursionDetected") } } impl ArcShiftCell { /// Create a new ArcShiftCell with the given value. pub fn new(value: T) -> ArcShiftCell { ArcShiftCell::from_arcshift(ArcShift::new(value)) } } impl ArcShiftCell { /// Creates an ArcShiftCell from an ArcShift-instance. ``` -------------------------------- ### ArcShiftCell::make_arcshift Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Creates an ArcShift instance pointing to the same value as the cell. ```APIDOC ### pub fn make_arcshift(&self) -> ArcShift Create an ArcShift-instance pointing to the same value as this cell. ``` -------------------------------- ### ArcShift Struct Definition Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShift.html?search= The definition of the ArcShift smart pointer structure. ```rust pub struct ArcShift { /* private fields */ } ``` -------------------------------- ### Implement Send and Clone for ArcShiftCell Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Defines thread-safety and cloning behavior for the ArcShiftCell container. ```rust unsafe impl Send for ArcShiftCell where T: Send + Sync {} impl Clone for ArcShiftCell { fn clone(&self) -> Self { // SAFETY: // Accessing the inner value is safe, since we know no other thread // can be interacting with it. And even if we're in a recursive call to // 'get', we're not mutating the value and cloning it is thus perfectly safe. let clone = unsafe { &mut *self.inner.get() }.clone(); ArcShiftCell { inner: UnsafeCell::new(clone), recursion: Cell::new(0), } } } ``` -------------------------------- ### ArcShiftCell::borrow Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Obtains a handle to the underlying value. ```APIDOC ### pub fn borrow(&self) -> ArcShiftCellHandle<'_, T> Get a handle to the pointed-to T. Make sure not to leak this handle as it may cause resource leaks. ``` -------------------------------- ### Define SharedGetGuard Enum Source: https://docs.rs/arcshift/0.4.4/arcshift/enum.SharedGetGuard.html The structure definition for the SharedGetGuard enum. ```rust pub enum SharedGetGuard<'a, T: ?Sized> { // some variants omitted } ``` -------------------------------- ### Assign a new ArcShift instance Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Replaces the current ArcShift instance with a clone of the provided one. Returns an error if called recursively. ```rust pub fn assign(&self, other: &ArcShift) -> Result<(), RecursionDetected> { if self.recursion.get() == 0 { // SAFETY: // Getting the inner value is safe, no other thread can be accessing it now *unsafe { &mut *self.inner.get() } = other.clone(); Ok(()) } else { Err(RecursionDetected) } } ``` -------------------------------- ### Conditional DropHandler Implementation Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper.rs.html Selects the appropriate DropHandler implementation based on feature flags like std and nostd_unchecked_panics. ```rust #[cfg(feature = "std")] pub(crate) use std_drop_handler::DropHandler; #[cfg(all(not(feature = "nostd_unchecked_panics"), not(feature = "std")))] pub(crate) use no_std_drop_handler::DropHandler; #[cfg(all(feature = "nostd_unchecked_panics", not(feature = "std")))] pub(crate) use unchecked_drop_handler::DropHandler; ``` -------------------------------- ### ArcShiftCellHandle Drop and Deref Implementations Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Handles the lifecycle and access logic for the ArcShiftCellHandle, including automatic reloading on drop. ```rust impl Drop for ArcShiftCellHandle<'_, T> { fn drop(&mut self) { let mut rec = self.cell.recursion.get(); rec -= 1; if rec == 0 { // SAFETY: // There are no references to 'inner', so it's safe to obtain // a mutable reference. unsafe { (*self.cell.inner.get()).reload() }; } self.cell.recursion.set(rec); } } impl Deref for ArcShiftCellHandle<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { if self.cell.recursion.get() == 1 { // SAFETY: // We're the only owner of the ArcShiftCell, and can thus get mutable access. let inner: &mut ArcShift = unsafe { &mut *self.cell.inner.get() }; inner.get() } else { // SAFETY: // Shared access to this UnsafeCell is always allowed. // Actual mutable references to the 'inner' never live long enough // to be visible by the user of this module. let inner: &ArcShift = unsafe { &*self.cell.inner.get() }; inner.shared_non_reloading_get() } } } ``` -------------------------------- ### Define ArcShiftWeak struct Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShiftWeak.html?search=u32+-%3E+bool The definition of the ArcShiftWeak struct. ```rust pub struct ArcShiftWeak { /* private fields */ } ``` -------------------------------- ### ArcShiftWeak::upgrade Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.ArcShiftWeak.html?search=u32+-%3E+bool Attempts to upgrade the weak reference to a full ArcShift instance. Returns Some(ArcShift) if the value still exists, or None if the original ArcShift has been deallocated. ```APIDOC ## pub fn upgrade(&self) -> Option> ### Description Upgrade this ArcShiftWeak instance to a full ArcShift. This is required to be able to access any stored value. If the ArcShift instance has no value (because the last ArcShift instance had been deallocated), this method returns None. ``` -------------------------------- ### ArcShiftCell::assign Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Assigns an ArcShift to the current instance. ```APIDOC ### pub fn assign(&self, other: &ArcShift) -> Result<(), RecursionDetected> Assign the given ArcShift to this instance. Returns Err if recursion is detected. ``` -------------------------------- ### Implement StealingDropHandler in Rust Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper/stealing_drop.rs.html Defines the StealingDropHandler struct and its implementation of IDropHandler to manage object stealing during drop cycles. ```rust 1use crate::deferred_panics_helper::DropHandler; 2use crate::deferred_panics_helper::IDropHandler; 3use crate::{debug_println, ItemHolder, SizedMetadata}; 4use core::ptr::addr_of_mut; 5 6/// A drop handler that will persist the most recent object, allowing 7/// it to be returned to the user. All other objects will be dropped. 8pub(crate) struct StealingDropHandler { 9 regular: DropHandler, 10 stolen: Option, 11 sole_user: bool, 12} 13 14impl Default for StealingDropHandler { 15 fn default() -> Self { 16 Self { 17 regular: Default::default(), 18 stolen: None, 19 sole_user: false, 20 } 21 } 22} 23 24impl StealingDropHandler { 25 pub(crate) fn take_stolen(self) -> Option { 26 self.regular.resume_any_panics(); 27 self.sole_user.then_some(self.stolen?) 28 } 29} 30impl IDropHandler for StealingDropHandler { 31 fn do_drop(&mut self, item_ptr: *mut ItemHolder) { 32 if let Some(prev) = self.stolen.take() { 33 self.regular.do_drop_value(prev) 34 } 35 // None of the below ops can panic 36 // SAFETY: item_ptr must be valid, guaranteed by caller. 37 let payload = unsafe { addr_of_mut!((*item_ptr).payload).read() }; 38 debug_println!("payload ref created (stealing drop)"); 39 // item_ptr is now uniquely owned. We can safely take it.. 40 let payload = core::mem::ManuallyDrop::into_inner(payload.into_inner()); 41 self.stolen = Some(payload); 42 debug_println!("payload stolen"); 43 } 44 45 fn report_sole_user(&mut self) { 46 self.sole_user = true; 47 } 48} ``` -------------------------------- ### ArcShiftCell::from_arcshift Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Creates an ArcShiftCell from an existing ArcShift instance without cloning the payload. ```APIDOC ### pub fn from_arcshift(input: ArcShift) -> ArcShiftCell Creates an ArcShiftCell from an ArcShift-instance. The payload is not cloned, the two pointers keep pointing to the same object. ``` -------------------------------- ### ArcShiftCell and ArcShiftCellHandle Definitions Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Defines the ArcShiftCell structure and its associated handle for accessing the contained value. ```rust pub struct ArcShiftCell { // UnsafeCell makes ArcShiftCell invariant, which it needs to be inner: UnsafeCell>, recursion: Cell, } /// A handle to the pointed-to value of a ArcShiftCell. This handle should not be leaked, /// but if it is leaked, the effect is that whatever value the ArcShiftCell-instance /// pointed to at that time, will forever leak also. All the linked-list nodes from /// that entry and onward will also leak. So make sure to not leak the handle! /// /// Leaking the handle does not cause unsoundness and is not UB. pub struct ArcShiftCellHandle<'a, T: 'static + ?Sized> { cell: &'a ArcShiftCell, // Make sure ArcShiftCellHandle is neither Sync nor Send, and also invariant _marker: PhantomData<*mut T>, } ``` -------------------------------- ### Define IDropHandler Trait Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper.rs.html Defines the interface for handling drops, including reporting the sole user status. ```rust pub(crate) trait IDropHandler { fn do_drop(&mut self, ptr: *mut ItemHolder); /// Call this if fn report_sole_user(&mut self); } ``` -------------------------------- ### ArcShiftCell::reload Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Reloads the ArcShiftCell instance to drop unused heap blocks. ```APIDOC ### pub fn reload(&self) Reload this ArcShiftCell-instance. This allows heap blocks kept alive by this instance of ArcShiftCell to be dropped. ``` -------------------------------- ### ArcShiftCell::reload Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=std%3A%3Avec Triggers a reload of the ArcShiftCell instance. ```APIDOC ## fn reload(&self) ### Description Allows heap blocks kept alive by this instance to be dropped. This method has no effect if called from within a `get` closure. ``` -------------------------------- ### ArcShiftCell Struct Definition Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= The definition of the ArcShiftCell struct. ```rust pub struct ArcShiftCell { /* private fields */ } ``` -------------------------------- ### ArcShift RCU Update Method Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper.rs.html?search=u32+-%3E+bool Atomically updates the value stored in ArcShift. ```rust &mut ArcShift, FnMut (&T) -> Option -> bool ``` -------------------------------- ### ArcShiftCell::get Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html?search=u32+-%3E+bool Accesses the value pointed to by the cell. ```APIDOC ## fn get(&self, f: impl FnOnce(&T) -> R) -> R ### Description Get the value pointed to. This method is fast and reentrant, allowing calls from within the closure 'f'. ``` -------------------------------- ### Borrow an ArcShiftCellHandle Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Obtains a handle to the inner value. Ensure the handle is not leaked to avoid resource leaks. ```rust #[inline] pub fn borrow(&self) -> ArcShiftCellHandle<'_, T> { self.recursion.set(self.recursion.get() + 1); ArcShiftCellHandle { cell: self, _marker: PhantomData, } } ``` -------------------------------- ### Define NoLongerAvailableMarker struct Source: https://docs.rs/arcshift/0.4.4/arcshift/struct.NoLongerAvailableMarker.html The definition of the NoLongerAvailableMarker struct, which contains private fields to prevent direct instantiation. ```rust pub struct NoLongerAvailableMarker { /* private fields */ } ``` -------------------------------- ### ArcShiftCellHandle Struct Definition Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCellHandle.html?search=std%3A%3Avec The definition of the ArcShiftCellHandle struct. ```rust pub struct ArcShiftCellHandle<'a, T: 'static + ?Sized> { /* private fields */ } ``` -------------------------------- ### ArcShiftCell::get Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.ArcShiftCell.html?search= Accesses the value pointed to by the cell using a closure. ```APIDOC ### pub fn get(&self, f: impl FnOnce(&T) -> R) -> R Get the value pointed to. This method is reentrant and performs a reload if necessary. ``` -------------------------------- ### Define IDropHandler Trait and Conditional DropHandler Implementation Source: https://docs.rs/arcshift/0.4.4/src/arcshift/deferred_panics_helper.rs.html?search=std%3A%3Avec Defines the IDropHandler trait for managing object drops and conditionally exports the appropriate DropHandler implementation based on feature flags. ```rust 1//! This module contains routines to help ensure that panicking drop-implementations 2//! do not cause corruption in the heap data-structures. The strategy to achieve 3//! this differs depending on if we run in `no_std` case or not. 4//! While running in `no_std`, dropping is deferred until after all lock-free memory 5//! structures have been updated, at some extra cost. 6//! When not using `no_std`, `catch_unwind` is used to catch panics and resume them 7//! when it is safe. 8use crate::{IMetadata, ItemHolder}; 9 10pub(crate) trait IDropHandler { 11 fn do_drop(&mut self, ptr: *mut ItemHolder); 12 /// Call this if 13 fn report_sole_user(&mut self); 14} 15 16#[cfg(feature = "std")] 17pub(crate) mod std_drop_handler; 18 19#[cfg(all(not(feature = "nostd_unchecked_panics"), not(feature = "std")))] 20pub(crate) mod no_std_drop_handler; 21 22#[cfg(all(feature = "nostd_unchecked_panics", not(feature = "std")))] 23pub(crate) mod unchecked_drop_handler; 24 25#[cfg(feature = "std")] 26pub(crate) use std_drop_handler::DropHandler; 27 28#[cfg(all(not(feature = "nostd_unchecked_panics"), not(feature = "std")))] 29pub(crate) use no_std_drop_handler::DropHandler; 30 31#[cfg(all(feature = "nostd_unchecked_panics", not(feature = "std")))] 32pub(crate) use unchecked_drop_handler::DropHandler; 33pub(crate) mod stealing_drop; ``` -------------------------------- ### Define RecursionDetected struct Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/struct.RecursionDetected.html?search=std%3A%3Avec The unit struct used to signal recursion errors within cell operations. ```rust pub struct RecursionDetected; ``` -------------------------------- ### RecursionDetected Error Type Source: https://docs.rs/arcshift/0.4.4/src/arcshift/cell.rs.html Defines the error type used when recursion is detected during operations. ```rust pub struct RecursionDetected; impl Debug for RecursionDetected { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "RecursionDetected") } } impl Display for RecursionDetected { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "RecursionDetected") } } ``` -------------------------------- ### arcshift::ArcShift::rcu_maybe Source: https://docs.rs/arcshift/0.4.4/arcshift/cell/index.html?search=u32+-%3E+bool Atomically update the value held by an ArcShift instance. This method takes a closure that receives a reference to the current value and returns an Option containing the new value to be set, returning a boolean indicating if the update occurred. ```APIDOC ## rcu_maybe ### Description Atomically update the value. The method takes a closure that receives a reference to the current value and returns an Option. If the closure returns Some(new_value), the value is updated and the method returns true. If it returns None, no update is performed and the method returns false. ### Signature `pub fn rcu_maybe(&mut self, f: F) -> bool where F: FnMut(&T) -> Option` ### Parameters - **f** (FnMut(&T) -> Option) - A closure that determines the new value based on the current value. ### Returns - **bool** - Returns true if the value was updated, false otherwise. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.