<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<blockquote cite="mid:005c01cb8bad$30eb4840$92c1d8c0$@co.nz" type="cite">
<div class="WordSection1"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p></o:p></span>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">On
a more general point, I’d say that whilst referencing “self” as an
interface is an almost unavoidable part of any interface based
framework, the same is not true in the destructor. Anything referenced
or notified during destruction of an object that requires being passed
a reference TO that object, could and most likely should, have been
passed a reference to that object during construction or during some
later operation.<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p>However,
if those other objects were holding on to those references, that would
prevent the object from being destroyed in the first place.<o:p></o:p></span></p>
</div>
</blockquote>
During construction an object may interact with another object via its
interface, so that the contained object does not know what exact object
is calling its methods. There is no reason why it shouldn't do that in
its destructor as well.<br>
<blockquote cite="mid:005c01cb8bad$30eb4840$92c1d8c0$@co.nz" type="cite">
<div class="WordSection1">
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Another
thing that is missing is a safe, common implementation of a weak
reference (an interface reference that does not hold on to – i.e. does
not contribute +1 toward – the reference count of the referenced
object). You can use an interface reference cast as a Pointer, but the
catch is that the reference must be sure that it will be notified if
the referenced object is destroyed, so that it can NIL itself. Using a
plain Pointer won’t do... you have to wrap it inside some object that
can register for those notifications (and be sure that the object
referenced will implement the required notification for the wrapper to
respond to).</span></p>
</div>
</blockquote>
This is another scenario which could invoke a call to the container
object's interface.<br>
<blockquote cite="mid:005c01cb8bad$30eb4840$92c1d8c0$@co.nz" type="cite">
<div class="WordSection1">
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p>
<br>
</o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">But,
that is not a general purpose solution as it requires that objects
exposing interfaces that may be encapsulated in my weak reference
implementation also implement IOn_Destroy, which is not built into the
VCL. In fact, the VCL doesn’t have any such general purpose system
(and neither should it have imho). The FreeNotification() mechanism is
not supported on TObject, and neither imho should it be.<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
</div>
</blockquote>
I certainly wouldn't advocate putting FreeNotification on TObject. It
is far too convoluted. I was thinking more of an external observer, so
that TObject doesn't even know it is being watched. Since TObject's
only task would be to broadcast a message when it was being destroyed,
any observers would be responsible for severing the link.<br>
<blockquote cite="mid:005c01cb8bad$30eb4840$92c1d8c0$@co.nz" type="cite">
<div class="WordSection1">
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Not
every application – or indeed every object - needs these things, nor
the overhead that it would incur, adding housekeeping code to the
tear-down of every object.<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Most
applications simply don’t need these sorts of exotica (as evidenced by
the fact that these sort of facilities either don’t exist at all or
took so long to be introduced into the core VCL, following the
introduction of interfaces waaaaaay back in Delphi 3 – Delphi 2 did
things slightly differently you may recall).<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
</div>
</blockquote>
I started with Delphi 4.<br>
<blockquote cite="mid:005c01cb8bad$30eb4840$92c1d8c0$@co.nz" type="cite">
<div class="WordSection1">
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">The
very beauty of Delphi and the VCL is that we can introduce these things
into the applications (or indeed the small parts of our applications)
that need them, without imposing them on everything else.<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">When
we want the convenience of having everything to hand whether you want
it or not, that’s what managed code is for. </span><span
style="font-size: 11pt; font-family: Wingdings; color: rgb(31, 73, 125);">J</span><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"><o:p> </o:p></span></p>
<div>
<div
style="border-style: solid none none; border-color: rgb(181, 196, 223) -moz-use-text-color -moz-use-text-color; border-width: 1pt medium medium; padding: 3pt 0cm 0cm;">
<p class="MsoNormal"><b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US">From:</span></b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US"> <a class="moz-txt-link-abbreviated" href="mailto:delphi-bounces@delphi.org.nz">delphi-bounces@delphi.org.nz</a>
[<a class="moz-txt-link-freetext" href="mailto:delphi-bounces@delphi.org.nz">mailto:delphi-bounces@delphi.org.nz</a>] <b>On Behalf Of </b>Todd<br>
<b>Sent:</b> Wednesday, 24 November 2010 8:08 p.m.<br>
<b>To:</b> NZ Borland Developers Group - Delphi List<br>
<b>Subject:</b> Re: [DUG] How's this for inconsistent<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Yep
– I remember that my fix was to set the “destructing” state indicator
in a BeforeDestruction() override. This was then tested in _Release()
to render it a NO-OP during execution of the destructor chain
(incomplete, obviously, just to give the idea):</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">
Procedure BeforeDestruction;</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">
SetState(csDestroying);</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">
Function _Release;</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">
If csDestroying in State then EXIT;</span><o:p></o:p></p>
<p class="MsoNormal">Upon reflection, that would only work for a
TComponent descendant. <o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Nothing
else needs be done, as long as any further BeforeDestruction overrides
call inherited before doing their work, which they should do (in my
framework I introduced another virtual to be overridden in my
descendants, in case there were occasions when work was done to
generate references during the destructor execution – even in your
case, the FreeInstance() override is redundant I think, other than as a
sanity/safety check and so could be made subject to some conditional
compilation flag.</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<div>
<div
style="border-style: solid none none; border-color: -moz-use-text-color; border-width: 1pt medium medium; padding: 3pt 0cm 0cm;">
<p class="MsoNormal"><b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US">From:</span></b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US"> <a moz-do-not-send="true"
href="mailto:delphi-bounces@delphi.org.nz">delphi-bounces@delphi.org.nz</a>
[<a moz-do-not-send="true" href="mailto:delphi-bounces@delphi.org.nz">mailto:delphi-bounces@delphi.org.nz</a>]
<b>On Behalf Of </b>Todd<br>
<b>Sent:</b> Wednesday, 24 November 2010 6:15 p.m.<br>
<b>To:</b> NZ Borland Developers Group - Delphi List<br>
<b>Subject:</b> Re: [DUG] How's this for inconsistent</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Actually, this would be better<br>
<br>
<span style="font-size: 10pt;">function TamObject._Release: Integer;<br>
begin<br>
Result := InterlockedDecrement(FCount);<br>
if (FCount = 0) then<br>
begin<br>
//add a reference count, incase an interface is acquired and
released during destruction<br>
InterlockedIncrement(FCount);<br>
self.Destroy;<br>
end;<br>
end; </span><br>
<br>
<span style="font-size: 10pt;">procedure TamObject.FreeInstance;<br>
begin<br>
//remove the reference count added in _Release</span><br>
<span style="font-size: 10pt;"> InterlockedDecrement(FCount);<br>
assert(FCount = 0,'Destroying object with non-zero reference count');<br>
inherited FreeInstance;<br>
end;</span><br>
<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">I
spotted that they fixed that a while ago – I remember having to fix the
issue myself many years ago so was quite pleased to see that it was now
taken care of in TInterfaceObject as a matter of course. For some
reason I never noticed the omission of the same facility in the
destructor. And yes, it’s a [potentially] big problem.</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">I
need to think about this tho... setting a fake ref count during
execution of the constructor is safe enough as you know precisely when
construction is done and to restore the ref count back to zero.</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Setting
a fake ref count during destruction strikes me as more problematic and
makes me nervous, but I can’t quite put my finger on why. It might be
nothing. That doesn’t mean it can’t be fixed, only that the solution
put in place for construction might not work for destruction and it
wasn’t felt necessary to do any extra work for a more comprehensive
solution.</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">Certainly
in the case of my code where I fixed this I had specific “constructing”
/ “destructing” state markers (it wasn’t a general purpose
interfacedobject class but a base class in a far richer framework that
happened to also implement its own version of IUnknown) – I know I
didn’t rely on side effects of a faked ref count.</span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);"> </span><o:p></o:p></p>
<div>
<div
style="border-style: solid none none; border-color: -moz-use-text-color; border-width: 1pt medium medium; padding: 3pt 0cm 0cm;">
<p class="MsoNormal"><b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US">From:</span></b><span
style="font-size: 10pt; font-family: "Tahoma","sans-serif"; color: windowtext;"
lang="EN-US"> <a moz-do-not-send="true"
href="mailto:delphi-bounces@delphi.org.nz">delphi-bounces@delphi.org.nz</a>
[<a moz-do-not-send="true" href="mailto:delphi-bounces@delphi.org.nz">mailto:delphi-bounces@delphi.org.nz</a>]
<b>On Behalf Of </b>Todd<br>
<b>Sent:</b> Wednesday, 24 November 2010 16:55<br>
<b>To:</b> NZ Borland Developers Group - Delphi List<br>
<b>Subject:</b> [DUG] How's this for inconsistent</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">The Delphi developer who implemented
TInterfacedObject obviously considered the case when an interface
reference is grabbed during construction......<br>
<br>
<span style="font-size: 10pt;">// Set an implicit refcount so that
refcounting<br>
// during construction won't destroy the object.<br>
class function TInterfacedObject.NewInstance: TObject;<br>
begin<br>
Result := inherited NewInstance;<br>
TInterfacedObject(Result).FRefCount := 1;<br>
end;<br>
<br>
procedure TInterfacedObject.AfterConstruction;<br>
begin<br>
// Release the constructor's implicit refcount<br>
InterlockedDecrement(FRefCount);<br>
end;</span><br>
<br>
but didn't consider applying the same logic during destruction. So
grabing an interface reference during destruction causes all hell to
break loose, as the _Release method tries to free the object again and
again recursively.<br>
<br>
<span style="font-size: 10pt;">procedure
TInterfacedObject.BeforeDestruction;<br>
begin<br>
if RefCount <> 0 then<br>
Error(reInvalidPtr);<br>
end;</span><br>
<br>
<span style="font-size: 10pt;">function TInterfacedObject._Release:
Integer;<br>
begin<br>
Result := InterlockedDecrement(FRefCount);<br>
if Result = 0 then<br>
Destroy;<br>
end;</span><br>
<br>
Todd.<o:p></o:p></p>
<pre> <o:p></o:p></pre>
<pre> <o:p></o:p></pre>
<pre>_______________________________________________<o:p></o:p></pre>
<pre>NZ Borland Developers Group - Delphi mailing list<o:p></o:p></pre>
<pre>Post: <a moz-do-not-send="true"
href="mailto:delphi@delphi.org.nz">delphi@delphi.org.nz</a><o:p></o:p></pre>
<pre>Admin: <a moz-do-not-send="true"
href="http://delphi.org.nz/mailman/listinfo/delphi">http://delphi.org.nz/mailman/listinfo/delphi</a><o:p></o:p></pre>
<pre>Unsubscribe: send an email to <a moz-do-not-send="true"
href="mailto:delphi-request@delphi.org.nz">delphi-request@delphi.org.nz</a> with Subject: unsubscribe<o:p></o:p></pre>
<p class="MsoNormal"> <o:p></o:p></p>
<pre><o:p> </o:p></pre>
<pre><o:p> </o:p></pre>
<pre>_______________________________________________<o:p></o:p></pre>
<pre>NZ Borland Developers Group - Delphi mailing list<o:p></o:p></pre>
<pre>Post: <a moz-do-not-send="true"
href="mailto:delphi@delphi.org.nz">delphi@delphi.org.nz</a><o:p></o:p></pre>
<pre>Admin: <a moz-do-not-send="true"
href="http://delphi.org.nz/mailman/listinfo/delphi">http://delphi.org.nz/mailman/listinfo/delphi</a><o:p></o:p></pre>
<pre>Unsubscribe: send an email to <a moz-do-not-send="true"
href="mailto:delphi-request@delphi.org.nz">delphi-request@delphi.org.nz</a> with Subject: unsubscribe<o:p></o:p></pre>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: <a class="moz-txt-link-abbreviated" href="mailto:delphi@delphi.org.nz">delphi@delphi.org.nz</a>
Admin: <a class="moz-txt-link-freetext" href="http://delphi.org.nz/mailman/listinfo/delphi">http://delphi.org.nz/mailman/listinfo/delphi</a>
Unsubscribe: send an email to <a class="moz-txt-link-abbreviated" href="mailto:delphi-request@delphi.org.nz">delphi-request@delphi.org.nz</a> with Subject: unsubscribe</pre>
</blockquote>
<br>
</body>
</html>