Struct Revocable

Source
pub struct Revocable<T> { /* private fields */ }
Expand description

An object that can become inaccessible at runtime.

Once access is revoked and all concurrent users complete (i.e., all existing instances of RevocableGuard are dropped), the wrapped object is also dropped.

§Examples


struct Example {
    a: u32,
    b: u32,
}

fn add_two(v: &Revocable<Example>) -> Option<u32> {
    let guard = v.try_access()?;
    Some(guard.a + guard.b)
}

let v = KBox::pin_init(Revocable::new(Example { a: 10, b: 20 }), GFP_KERNEL).unwrap();
assert_eq!(add_two(&v), Some(30));
v.revoke();
assert_eq!(add_two(&v), None);

Sample example as above, but explicitly using the rcu read side lock.

use kernel::sync::rcu;

struct Example {
    a: u32,
    b: u32,
}

fn add_two(v: &Revocable<Example>) -> Option<u32> {
    let guard = rcu::read_lock();
    let e = v.try_access_with_guard(&guard)?;
    Some(e.a + e.b)
}

let v = KBox::pin_init(Revocable::new(Example { a: 10, b: 20 }), GFP_KERNEL).unwrap();
assert_eq!(add_two(&v), Some(30));
v.revoke();
assert_eq!(add_two(&v), None);

Implementations§

Source§

impl<T> Revocable<T>

Source

pub fn new(data: impl PinInit<T>) -> impl PinInit<Self>

Creates a new revocable instance of the given data.

Source

pub fn try_access(&self) -> Option<RevocableGuard<'_, T>>

Tries to access the revocable wrapped object.

Returns None if the object has been revoked and is therefore no longer accessible.

Returns a guard that gives access to the object otherwise; the object is guaranteed to remain accessible while the guard is alive. In such cases, callers are not allowed to sleep because another CPU may be waiting to complete the revocation of this object.

Source

pub fn try_access_with_guard<'a>(&'a self, _guard: &'a Guard) -> Option<&'a T>

Tries to access the revocable wrapped object.

Returns None if the object has been revoked and is therefore no longer accessible.

Returns a shared reference to the object otherwise; the object is guaranteed to remain accessible while the rcu read side guard is alive. In such cases, callers are not allowed to sleep because another CPU may be waiting to complete the revocation of this object.

Source

pub fn try_access_with<R, F: FnOnce(&T) -> R>(&self, f: F) -> Option<R>

Tries to access the wrapped object and run a closure on it while the guard is held.

This is a convenience method to run short non-sleepable code blocks while ensuring the guard is dropped afterwards. Self::try_access carries the risk that the caller will forget to explicitly drop that returned guard before calling sleepable code; this method adds an extra safety to make sure it doesn’t happen.

Returns None if the object has been revoked and is therefore no longer accessible, or the result of the closure wrapped in Some. If the closure returns a Result then the return type becomes Option<Result<>>, which can be inconvenient. Users are encouraged to define their own macro that turns the Option into a proper error code and flattens the inner result into it if it makes sense within their subsystem.

Source

pub unsafe fn revoke_nosync(&self)

Revokes access to and drops the wrapped object.

Access to the object is revoked immediately to new callers of Revocable::try_access, expecting that there are no concurrent users of the object.

§Safety

Callers must ensure that there are no more concurrent users of the revocable object.

Source

pub fn revoke(&self)

Revokes access to and drops the wrapped object.

Access to the object is revoked immediately to new callers of Revocable::try_access.

If there are concurrent users of the object (i.e., ones that called Revocable::try_access beforehand and still haven’t dropped the returned guard), this function waits for the concurrent access to complete before dropping the wrapped object.

Trait Implementations§

Source§

impl<T> Drop for Revocable<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T> HasPinData for Revocable<T>

Source§

type PinData = __ThePinData<T>

Source§

unsafe fn __pin_data() -> Self::PinData

Source§

impl<T> PinnedDrop for Revocable<T>

Source§

fn drop(self: Pin<&mut Self>, _: OnlyCallFromDrop)

Executes the pinned destructor of this type. Read more
Source§

impl<T: Send> Send for Revocable<T>

Source§

impl<T: Sync + Send> Sync for Revocable<T>

Auto Trait Implementations§

§

impl<T> !Freeze for Revocable<T>

§

impl<T> !RefUnwindSafe for Revocable<T>

§

impl<T> UnwindSafe for Revocable<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, E> Init<T, E> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, E> PinInit<T, E> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.