token-ref-cell
This library provides TokenRefCell
, an interior mutability cell which uses an
external Token
reference to synchronize its accesses.
Contrary to other standard cells like RefCell
, TokenRefCell
is Sync
as long as its token is Send + Sync
; it can thus be used in multithreaded programs.
Multiple token implementations are provided, the easiest to use being the
smart-pointer-based ones: every Box<T>
can indeed be used as a token (as long as T
is not a ZST). The recommended token implementation is BoxToken
, and it's the
default value of the generic parameter of TokenRefCell
.
The runtime cost is very lightweight: only one pointer comparison for
TokenRefCell::borrow
/TokenRefCell::borrow_mut
when using BoxToken
(and zero-cost when using singleton_token!
).
Because one token can be used with multiple cells, it's possible for example to use
a single rwlock wrapping a token to synchronize mutable access to multiple Arc
data.
Examples
use ;
use ;
let mut token = new;
// Initialize a vector of arcs
let token_ref = token.read.unwrap;
let arc_vec = vec!;
drop;
// Use only one rwlock to write to all the arcs
let mut token_mut = token.write.unwrap;
for cell in &arc_vec
drop
Why another crate?
Many crates based on the same principle exists: qcell
, ghost-cell
, token-cell
, singleton-cell
, etc.
When I started writing token-ref-cell
, I only knew token-cell
one, as it was written by a guy previously working in the same company as me. But I wanted to take a new approach, notably designing an API closer than standard RefCell
one, hence the name TokenRefCell
. In fact, my goal was simple: to make the graph example compile, and for that I needed to enable "re-borrowing", i.e. reusing the token used in a mutable borrow to mutably borrow a "sub-cell".
When I was satisfied with the result, before publishing it, I search for other similar crates, and I found the list above, and realized I'd reimplemented the same concept as a bunch of people, especially qcell
which uses a Box
for its cell token/owner. However, this fresh implementation still has a few specificities which makes it relevant:
- a familiar API close to
RefCell
one; - a unified API with a single
Token
trait, contrary toqcell
which provides four different cell types; - a larger choice of token implementations, thanks to the simplicity of the
Token
trait: singleton types, smart-pointers, pinned/unpinned references, etc.; no_std
implementation, compatible with custom allocators (doesn't requirealloc
crate, and doesn't require allocator at all usingRefToken
for example);- re-borrowing.