[][src]Function flize::unprotected

pub unsafe fn unprotected() -> &'static UnprotectedShield

Returns a reference to a dummy shield that allows unprotected access to Atomics.

This shield will not keep any thread pinned, it just allows interacting with Atomics 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.
}