Skip to main content

Module irc

Module irc 

Source
Available on crate feature irc only.
Expand description

Intrusive Reference Counter (Irc)

Irc is an intrusive reference counting smart pointer, similar to Arc but without weak reference support. It requires the inner type to implement IrcItem trait to provide a counter field.

The underlayer of Irc is Box, unlike Arc which wrap a hidden ArcInner on your inner types, Irc use the same memory location of your inner types.

IrcItem::on_drop in the trait allow you to have the ownship of underlying inner memory after the reference count of Irc is dropped.

§Example

use embed_collections::irc::{Irc, IrcItem};
use core::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
use crossfire::oneshot;
use std::thread;
use std::time::Duration;

// Usually we use Irc for some large structure, but we show a simple demo here.
struct MyItem {
    is_done: AtomicBool,
    counter: AtomicUsize,
    done_tx: Option<oneshot::TxOneshot<Box<MyItem>>>,
}

unsafe impl IrcItem<()> for MyItem {
    type Counter = AtomicUsize;
    fn counter(&self) -> &Self::Counter {
        &self.counter
    }

    // overwrite default behavior to send the item through channel
    fn on_drop(mut this: Box<Self>) {
        let done_tx = this.done_tx.take().unwrap();
        done_tx.send(this);
    }
}

let (done_tx, done_rx) = oneshot::oneshot();
let boxed_item = Box::new(MyItem {
    is_done: AtomicBool::new(false),
    counter: AtomicUsize::new(0),
    done_tx: Some(done_tx),
});

// Convert from Box to Irc, which does not have additional allocation.
let item = Irc::<_, ()>::from(boxed_item);
thread::spawn(move || {
    thread::sleep(Duration::from_secs(1));
    item.is_done.store(true, Ordering::SeqCst);
    drop(item);
});
let item: Box<MyItem> = done_rx.recv().unwrap();
assert!(item.is_done.load(Ordering::SeqCst));

Structs§

Irc
Intrusive reference counter, which support conversion bwteween Box<T>.

Traits§

IrcItem
trait for types that can be wrapped by Irc