Reference counted containers prototype
Michel Fortin
michel.fortin at michelf.com
Mon Dec 26 10:46:13 PST 2011
On 2011-12-26 17:25:10 +0000, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:
> Hello,
>
>
> I've been playing with a new approach to reference counting, in
> particular for the containers library.
>
> A small prototype is at http://pastebin.com/WnSQY1Jw. The prototype
> features a simple doubly-linked list implementation DListImpl. That is
> not supposed to be manipulated directly (or it might, in case the user
> wants a simple garbage collected implementation - this is a point in
> the discussion).
>
> DListImpl has only a couple of primitives implemented. The only
> interesting points that it tries to make are:
>
> (a) the presence of the dispose() primitive, which deallocates all
> memory and brings the object back to its .init state
>
> (b) the presence of the dup() primitive, which creates a full-blown
> duplicate of the object.
>
> The interesting part of the sample is RefImpl, which has a couple of
> quite interesting details:
>
> (a) All interaction with the held object is done via opDispatch. In
> fact opDispatch can be engineered to statically enforce no reference to
> the held object escapes.
>
> (b) A const/immutable call against a non-existing is silently converted
> into a call against a default-initialized object.
>
> (c) If a call works and returns the same type for a non-const and a
> const object, then the const version is preferred. This is to reduce
> the number of calls to ensureUnique().
>
> Destroy.
The overall design is quite sound and coherent. And you are cleanly
separating the reference counting policy from the container's
implementation. It fits with AAs. I also like that you can create a
DListImpl without indirection (on the stack or as a struct member) or
with a standard GC pointer if you so wish. So I don't see anything to
complain about in this design. Although I am a little concerned by this
small but important implementation detail:
Your RefCounted destructor is racy.
Just like other reference counted things in Phobos, if you somehow
store a reference on the GC heap (as a class member for instance), the
destructor for that reference struct is called from the GC thread and
will decrement the counter from that thread, while another reference
could play with the counter from another thread. I know you have plans
for a general fix for that hole in destructors, but meanwhile it'd be
wise to change the counter to a shared uint and use atomic operations
to avoid low level races.
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list