March 03, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Volodymyr | On 3/3/15 12:53 AM, Volodymyr wrote: > On Thursday, 26 February 2015 at 21:50:56 UTC, Andrei Alexandrescu wrote: >> http://wiki.dlang.org/DIP74 got to reviewable form. Please destroy and >> discuss. >> >> Thanks, >> >> Andrei > > With opAddRef/opRelease class does respondible for its dealocation and > its own payload so breaks SOLID's single responsibility principle. Correct. That's a tactical matter that can be addressed e.g. with mixin templates. > As > for me better design will be to do it closer to C++'s shared_ptr. > e.g: > > // maybe with @arc > struct RefCounter(T) > { > void opAddRef(); > void opRelease(); > ref T obj; > ref size_t count; > } > } > > RefCounter!Widged myRefToWidget; > > RefCounter with default ctor/dtor. opAddRef and opRelease is for > compiler optimtimisation and elimination of redunadant ref counter > increment/decrement. We couldn't make that work with safety. Andrei |
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 3 March 2015 at 09:58:12 UTC, Andrei Alexandrescu wrote:
> On 3/3/15 12:53 AM, Volodymyr wrote:
>> On Thursday, 26 February 2015 at 21:50:56 UTC, Andrei Alexandrescu wrote:
>>> http://wiki.dlang.org/DIP74 got to reviewable form. Please destroy and
>>> discuss.
>>>
>>> Thanks,
>>>
>>> Andrei
>>
>> With opAddRef/opRelease class does respondible for its dealocation and
>> its own payload so breaks SOLID's single responsibility principle.
>
> Correct. That's a tactical matter that can be addressed e.g. with mixin templates.
>
>> As
>> for me better design will be to do it closer to C++'s shared_ptr.
>> e.g:
>>
>> // maybe with @arc
>> struct RefCounter(T)
>> {
>> void opAddRef();
>> void opRelease();
>> ref T obj;
>> ref size_t count;
>> }
>> }
>>
>> RefCounter!Widged myRefToWidget;
>>
>> RefCounter with default ctor/dtor. opAddRef and opRelease is for
>> compiler optimtimisation and elimination of redunadant ref counter
>> increment/decrement.
>
> We couldn't make that work with safety.
>
>
> Andrei
Why couldn't? Let's for all @return (this) functions make wrappers that rerturn RefCounter!MemberType(member, ownerCounterPtr), and same thing for public fields
The wrapper nedded only for realy owned resources (but not simple gc's refs).
|
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Implicit conversion to supertypes (class or interface) is allowed ONLY if the supertype is also a reference counted type. It follows that reference counted types cannot be converted to Object (unless Object itself defines the two methods). But how about calling methods of supertypes? class Basic { Basic castToBasic() return { return this; } } class RCWidged : Basic { void opAddRef(); void opRelease(); // etc } Object a; { auto b = RCWidget; a = b.castToBasic; // unsafe? opAddReff? // b.opRelease? } a < new RCWidget // call to Object.opCmp. Error? The problem with shared_ptr-like solution - "this" parameter is not shared_ptr. You try to build shared_ptr into "this". But basic class knows nothing about RC in child class. And those who use the basic class know nothing. RefCounter is unsafe and mutable. Let's do it universal (for classes/value structs/ and unions), add method auto opShareResource(T)(ref T t) to handle parts of RC class that go away. auto opShareResource(T)(ref T t) { return RefCounter!T(t, ownerRefCounter); } this method will be called for direct or indirect access to fields of RCClass and may wrap resource or throw or do anything else. |
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Volodymyr | On 3/4/15 5:08 AM, Volodymyr wrote: > Implicit conversion to supertypes (class or interface) is allowed > ONLY if the supertype is also a reference counted type. It > follows that reference counted types cannot be converted to > Object (unless Object itself defines the two methods). > > But how about calling methods of supertypes? That also entails an implicit conversion. To clarify, I added this to http://wiki.dlang.org/DIP74#General: "Method calls to supertypes are only allowed if the supertype that defines the method is also reference counted." Andrei |
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | After looking at DIP74, it seems that there is no way to create a weak reference to a ref counted object, but is not explicitly stated. Has this idea been considered at all? |
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On 3/4/15 10:48 AM, bitwise wrote:
> After looking at DIP74, it seems that there is no way to create a weak
> reference to a ref counted object, but is not explicitly stated. Has
> this idea been considered at all?
DIP74 aims at not disallowing weak references whilst leaving it to libraries to effect implementations, but we'd need a proof of concept implementation to make sure DIP74 is enough as is. -- Andrei
|
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Wednesday, 4 March 2015 at 18:59:54 UTC, Andrei Alexandrescu wrote:
> On 3/4/15 10:48 AM, bitwise wrote:
>> After looking at DIP74, it seems that there is no way to create a weak
>> reference to a ref counted object, but is not explicitly stated. Has
>> this idea been considered at all?
>
> DIP74 aims at not disallowing weak references whilst leaving it to libraries to effect implementations, but we'd need a proof of concept implementation to make sure DIP74 is enough as is. -- Andrei
I suppose you could add "getWeak()" and "releaseWeak()" to a ref counted class, and implement a "struct Weak(T)" that calls them for you, but I doesn't seem like much of a leap to just add something like this to the DIP.
couldn't "opAddWeak" and "opReleaseWeak" be added and follow identical rules to "opAddRef" and "opRelease"? The compiler could simply insert "opAddWeak() instead of opAddRef() when it found the "weak" keyword.
For example:
class Widget {
private uint _refs = 1;
private uint _weaks = 0;
private int[] _payload; // owned
void opAddRef() {
++_refs;
}
void opRelease() {
if (--_refs == 0) {
GC.free(_payload.ptr);
_payload = null;
// I'm assuming this would leave "_weaks" and "_refs" untouched
this.destroy();
if(_weaks == 0) {
GC.free(cast(void*)this);
}
}
}
void opAddWeak() {
++_weaks;
}
void opReleaseWeak() {
if(--_weaks == 0 && _refs == 0) {
GC.free(cast(void*)this);
}
}
// optional/recommended
bool expired() {
return _refs == 0;
}
}
Widget a = new Widget; // refs == 1, weaks == 0
Widget b = weak a; // refs == 1, weaks == 1
//a.opAddWeak();
Widget c = b;
// b.opAddRef(); // refs == 2, weaks == 1
a = null; // refs == 1, weaks == 1
//a.opRelease();
assert(b.expired() == false);
c = null; // refs == 0, weaks == 1
// c.opRelease();
assert(b.expired() == true);
b = null; // refs == 0, weaks == 0
// b.opReleaseWeak();
////////// or for function calls:
void func(weak Widget a) {
//...
}
Widget a = new Widget;
func(a);
|
March 04, 2015 Re: DIP74: Reference Counted Class Objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On 3/4/15 12:04 PM, bitwise wrote:
> I suppose you could add "getWeak()" and "releaseWeak()" to a ref counted
> class
My initial attempt would be to see if opAddRef and opRelease defined by a distinct weak pointer type would work. -- Andrei
|
Copyright © 1999-2021 by the D Language Foundation