Struct sharded_slab::pool::OwnedRefMut[][src]

pub struct OwnedRefMut<T, C = DefaultConfig> where
    T: Clear + Default,
    C: Config
{ /* fields omitted */ }

An owned guard that allows exclusive, mutable access to an object in a pool.

An OwnedRefMut<T> functions more or less identically to an owned Box<T>: it can be passed to functions, stored in structure fields, and borrowed mutably or immutably, and can be owned for arbitrary lifetimes. The difference is that, unlike a Box<T>, the memory allocation for the T lives in the Pool; when an OwnedRefMut is created, it may reuse memory that was allocated for a previous pooled object that has been cleared. Additionally, the OwnedRefMut may be downgraded to an OwnedRef which may be shared freely, essentially turning the Box into an Arc.

This is returned by Pool::create_owned.

While the guard exists, it indicates to the pool that the item the guard references is currently being accessed. If the item is removed from the pool while the guard exists, theremoval will be deferred until all guards are dropped.

Unlike RefMut, which borrows the pool, an OwnedRefMut clones the Arc around the pool. Therefore, it keeps the pool from being dropped until all such guards have been dropped. This means that an OwnedRefMut may be held for an arbitrary lifetime.

Examples

use std::sync::Arc;

let pool: Arc<Pool<String>> = Arc::new(Pool::new());

// Create a new pooled item, returning an owned guard that allows mutable
// access to the new item.
let mut item = pool.clone().create_owned().unwrap();
// Return a key that allows indexing the created item once the guard
// has been dropped.
let key = item.key();

// Mutate the item.
item.push_str("Hello");
// Drop the guard, releasing mutable access to the new item.
drop(item);

/// Other threads may now (immutably) access the item using the returned key.
thread::spawn(move || {
   assert_eq!(pool.get(key).unwrap(), String::from("Hello"));
}).join().unwrap();
use std::sync::Arc;

let pool: Arc<Pool<String>> = Arc::new(Pool::new());

// Create a new item, returning an owned, mutable guard.
let mut value = pool.clone().create_owned().unwrap();

// Now, the original `Arc` clone of the pool may be dropped, but the
// returned `OwnedRefMut` can still access the value.
drop(pool);

value.push_str("hello world");
assert_eq!(value, String::from("hello world"));

Unlike RefMut, an OwnedRefMut may be stored in a struct which must live for the 'static lifetime:

use sharded_slab::pool::OwnedRefMut;
use std::sync::Arc;

pub struct MyStruct {
    pool_ref: OwnedRefMut<String>,
    // ... other fields ...
}

// Suppose this is some arbitrary function which requires a value that
// lives for the 'static lifetime...
fn function_requiring_static<T: 'static>(t: &T) {
    // ... do something extremely important and interesting ...
}

let pool: Arc<Pool<String>> = Arc::new(Pool::new());

// Create a new item, returning a mutable owned reference.
let pool_ref = pool.clone().create_owned().unwrap();

let my_struct = MyStruct {
    pool_ref,
    // ...
};

// We can use `my_struct` anywhere where it is required to have the
// `'static` lifetime:
function_requiring_static(&my_struct);

OwnedRefMuts may be sent between threads:

use std::{thread, sync::Arc};

let pool: Arc<Pool<String>> = Arc::new(Pool::new());

let mut value = pool.clone().create_owned().unwrap();
let key = value.key();

thread::spawn(move || {
    value.push_str("hello world");
    // ...
}).join().unwrap();

// Once the `OwnedRefMut` has been dropped by the other thread, we may
// now access the value immutably on this thread.

assert_eq!(pool.get(key).unwrap(), String::from("hello world"));

Downgrading from a mutable to an immutable reference:

use std::{thread, sync::Arc};

let pool: Arc<Pool<String>> = Arc::new(Pool::new());

let mut value = pool.clone().create_owned().unwrap();
let key = value.key();
value.push_str("hello world");

// Downgrade the mutable owned ref to an immutable owned ref.
let value = value.downgrade();

// Once the `OwnedRefMut` has been downgraded, other threads may
// immutably access the pooled value:
thread::spawn(move || {
    assert_eq!(pool.get(key).unwrap(), String::from("hello world"));
}).join().unwrap();

// This thread can still access the pooled value through the
// immutable owned ref:
assert_eq!(value, String::from("hello world"));

Implementations

impl<T, C> OwnedRefMut<T, C> where
    T: Clear + Default,
    C: Config
[src]

pub fn key(&self) -> usize[src]

Returns the key used to access this guard

pub fn downgrade(self) -> OwnedRef<T, C>[src]

Downgrades the owned mutable guard to an owned immutable guard, allowing access to the pooled value from other threads.

Examples

let pool = Arc::new(Pool::<String>::new());

let mut guard_mut = pool.clone().create_owned().unwrap();
let key = guard_mut.key();
guard_mut.push_str("Hello");

// The pooled string is currently borrowed mutably, so other threads
// may not access it.
let pool2 = pool.clone();
thread::spawn(move || {
    assert!(pool2.get(key).is_none())
}).join().unwrap();

// Downgrade the guard to an immutable reference.
let guard = guard_mut.downgrade();

// Now, other threads may also access the pooled value.
let pool2 = pool.clone();
thread::spawn(move || {
    let guard = pool2.get(key)
        .expect("the item may now be referenced by other threads");
    assert_eq!(guard, String::from("Hello"));
}).join().unwrap();

// We can still access the value immutably through the downgraded guard.
assert_eq!(guard, String::from("Hello"));

Trait Implementations

impl<T, C> Debug for OwnedRefMut<T, C> where
    T: Debug + Clear + Default,
    C: Config
[src]

impl<T, C> Deref for OwnedRefMut<T, C> where
    T: Clear + Default,
    C: Config
[src]

type Target = T

The resulting type after dereferencing.

impl<T, C> DerefMut for OwnedRefMut<T, C> where
    T: Clear + Default,
    C: Config
[src]

impl<T, C> Drop for OwnedRefMut<T, C> where
    T: Clear + Default,
    C: Config
[src]

impl<T, C> PartialEq<T> for OwnedRefMut<T, C> where
    T: PartialEq<T> + Clear + Default,
    C: Config
[src]

impl<T, C> Send for OwnedRefMut<T, C> where
    T: Sync + Clear + Default,
    C: Config
[src]

impl<T, C> Sync for OwnedRefMut<T, C> where
    T: Sync + Clear + Default,
    C: Config
[src]

Auto Trait Implementations

impl<T, C = DefaultConfig> !RefUnwindSafe for OwnedRefMut<T, C>

impl<T, C> Unpin for OwnedRefMut<T, C>

impl<T, C = DefaultConfig> !UnwindSafe for OwnedRefMut<T, C>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.