[fpc-devel] Suggestion: reference counted objects

Sven Barth pascaldragon at googlemail.com
Sat Sep 27 18:33:57 CEST 2014


On 27.09.2014 17:00, Constantine Yannakopoulos wrote:
> On Sat, Sep 27, 2014 at 4:36 PM, Sven Barth <pascaldragon at googlemail.com
> <mailto:pascaldragon at googlemail.com>> wrote:
>
>     There are however some nasty problems inside constructors and
>     destructors, because "Self" is reference counted as well (and should
>     be after all as we don't want the instance to be destroyed behind
>     our backs suddenly).
>
>
> The parenthesis can happen in Delphi interfaced objects as well. It is
> perfectly possible to lose the object from under your feet if the code
> of one of its methods ​leads to references reaching zero (e.g. removal
> from a strong-ref'd list). If such a possibility exists the developer
> needs to manually _AddRef/_Release (e.g. store Self in a local interface
> variable) if they need to access Self after that point, and that is
> perfectly OK. The only way to avoid that would be to emit code at a
> compiler-generated implicit try-finally block to _AddRef/_Release, which
> is a bad idea IMHO as it adds overhead when it won't be required for
> 99.99% of cases.

That's what the compiler currently does though, because it treats Self 
just a like a normal reference counted variable... Will need to check 
what I need to do do switch that of ;)

> As for destructors, the way refcounting is implemented in Delphi it
> prohibits performing _Addref/_Release (e.g. pass an interface variable
> of Self to an external method) in them because this will cause infinite
> recursion.

Huh? Delphi really prohibits such things inside the destructor? Would 
you mind to share an example (possibly including error messages), please?


> This problem has an easy solution: Override BeforeDestruction
> and set RefCount to a positive value, 1 or MaxInt div 2 (not -1,
> consider the sequence _AddRef[0], _AddRef[1], _Release[0-bang],
> _Release[AV]) after calling inherited (which checks for 0). Since the
> object destruction process has already started due to RefCount reaching
> zero, refcounting is useless at this point and can be safely disabled.
> You could consider doing this in your implementation.

I've done a different approach already: the decrease helper sets 
refcount to -1 directly before it calls the destructor and both the 
increase and the decrease helper check for -1. Considering that it's 
currently only a proof of concept I can live with the performance impact 
that comparison might have.

Regards,
Sven



More information about the fpc-devel mailing list