Chapter 6. Building Our Own “Arc”
In “Reference Counting”, we saw the std::sync::Arc<T>
type that allows for shared ownership through reference counting.
The Arc::new
function creates a new allocation, just like Box::new
.
However, unlike a Box
, a cloned Arc
will share the original
allocation, without creating a new one.
The shared allocation will only be dropped once the Arc
and all its clones are dropped.
The memory ordering considerations involved in an implementation of this type
can get quite interesting.
In this chapter, we’ll put more of the theory to practice by implementing our own Arc<T>
.
We’ll start with a basic version,
then extend it to support weak pointers for cyclic structures,
and finish the chapter with an optimized version
that’s nearly identical to the implementation in the standard library.
Basic Reference Counting
Our first version will use a single AtomicUsize
to count
the number of Arc
objects that share an allocation.
Let’s start with a struct that holds this counter and the
T
object:
struct
ArcData
<
T
>
{
ref_count
:AtomicUsize
,
data
:T
,
}
Note that this struct is not public.
It’s an internal implementation detail of our Arc
implementation.
Next is the Arc<T>
struct itself,
which is effectively just a pointer to a (shared) ArcData<T>
object.
It might be tempting to make it a wrapper for a Box<ArcData<T>>
,
using a standard Box
to handle the allocation of the ArcData<T>
.
However, a Box
represents exclusive ownership, not shared ownership. We can’t use ...
Get Rust Atomics and Locks now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.