[−][src]Function flize::unprotected
pub unsafe fn unprotected() -> &'static UnprotectedShield
Returns a reference to a dummy shield that allows unprotected access to Atomic
s.
This shield will not keep any thread pinned, it just allows interacting with Atomic
s
unsafely.
Thus, neither calling repin
nor repin_after
on a shield returned from this function will
actually re-pin the current thread. Calling repin_after
or retire
will execute the
supplied function immediately.
Safety
Loading and dereferencing data from an Atomic
using this guard is safe only if the Atomic
is not being concurrently modified by other threads.
Examples
use flize::{self, Atomic, Shared, Shield}; use std::sync::atomic::Ordering::Relaxed; use std::mem; let a = { let s: Shared<'_, i32> = unsafe { Shared::from_ptr(Box::into_raw(Box::new(7))) }; Atomic::new(s) }; unsafe { // Load `a` without pinning the current thread. let s = a.load(Relaxed, flize::unprotected()); assert_eq!(s.as_ref_unchecked(), &7); // It is possible to create more unprotected shields with `clone()`. let unprotected = &flize::unprotected().clone(); // Swap `a` with a new value (9) without pinning the current thread. let s = Shared::from_ptr(Box::into_raw(Box::new(9))); let s = a.swap(s, Relaxed, unprotected); assert_eq!(a.load(Relaxed, unprotected).as_ref_unchecked(), &9); assert_eq!(s.as_ref_unchecked(), &7); let ptr = a.load(Relaxed, unprotected).as_ptr(); unprotected.retire(move || { // This is executed immediately, thus `a` now holds an invalid pointer. drop(Box::from_raw(ptr)); }); // Dropping `unprotected` doesn't affect the current thread since it did not pin it. }