Two suggestions for safe refcounting

Zach the Mystic via Digitalmars-d digitalmars-d at puremagic.com
Fri Mar 6 14:41:14 PST 2015


On Friday, 6 March 2015 at 14:40:31 UTC, Volodymyr wrote:
> On Friday, 6 March 2015 at 07:46:13 UTC, Zach the Mystic wrote:
> ...
>> Note how the last member, opIndex, doesn't return a raw E*, 
>> but only an E* which is paired with a pointer to the same 
>> RCData instance as the RCArray is:
>>
>> struct RCElement(E) {
>>  E* element;
>>  private RCData* data;
>>
>>  this(this) {
>>    data.addRef();
>>  }
>>  ~this() {
>>    data.decRef();
>>  }
>> }
>>
>> This is the best I could do.
>
> It's needed to change type of this from RCArray to 
> tuple!(RCArray, RCData). But as for me better to use Array and 
> cahnge typeof(this) to RefCounter!Array:
> assert(typeid(typeof(this)) == typeid(RefCounter!Array));
>
> So how to deal with it:
> struct RefCounter(T) // this is struct!
> {
> void opAddRef();
> void opRelease();
> alias this = __data;
> void[] allocate(size_t)
>
> // Hendler for sharing owned resources
> auto opShareRes(MemberType)(ref MemberType field)
> {
>     return makeRefCounter(field, __count);
> }
>
> private:
> size_t __count;
> T __data;
> }
>
> @resource_owner(RefCounter)
> class Array
> {
> ref int opIndex(size_t i) return
> {
>     return _data[i];
> }
>
> //// opIndex will be replaced with this function
> //RefCounter!int opIndex(size_t i) // @return?
> //{
> //    assert(typeid(this) == typeid(RefCounter!Array));
> //    return this.opShareResource(_data[i]);
> //    // after inlining: return makeRefCounter(_data[i], 
> __count);
> //}
>
> private int[] _data;
> }
>
> Method opShareRes is to move resources away(share with other 
> owner) and an @return method will change its return type to 
> opSharedRes return type. opShareRes also wraps access to public 
> fields(and may change type of result).
>
> Now Array is actualy alias to RefCounter!Array. Array creation 
> is special case. "new Array" have to use 
> RefCounter!Array.allocate. So owner manage array parts sharing, 
> allocation and removing.
>
> Options for @resource_owner
> @resource_owner(this) - class provides 
> opAddRef/opRelease/opShareRes by itself as in DIP74
> @resource_owner(this, MyRCMixin) - MyRCMixin provides 
> opAddRef/opRelease/opShareRes and will be mixed in class.(What 
> DIP74 has in mind)
> @resource_owner(Owner) - Owner is a template. Whenever you use 
> owned type T it will be replaced with Owner!T(even type of 
> "this"). This case prohibits changing owning strategy.

You've packed a lot of ideas into one post. Your solution might 
work, but it's hard for me to tell.

> Resourse owning is close to memory management. Maybe resource 
> owner have to set memory allocation strategy instead of 
> providing method allocate.

This is an open question. I'm still wrestling with understanding 
all the interlocking systems. The only reason I keep exploring 
them is that sometimes it seems like nobody else understands them 
either. ^_^


More information about the Digitalmars-d mailing list