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>.