<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#ffffff">
<br>
<blockquote cite="mid:004201cb8ba0$8c122a20$a4367e60$@co.nz" type="cite">
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
span.EmailStyle17
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;
        color:black;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<div class="WordSection1">
<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):<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);">
Procedure BeforeDestruction;<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size: 11pt; font-family: "Calibri","sans-serif"; color: rgb(31, 73, 125);">
SetState(csDestroying);<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);">
Function _Release;<o:p></o:p></span></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;<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);">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></p>
</div>
</blockquote>
True. I used an "assert", since it can be eliminated by the compiler,
but the decrement still remains.<br>
There's always more than one way to skin the cat. I like the do/undo
pattern.<br>
<br>
The whole problem could be eliminated entirely if TInterfacedObject
just broadcast a message when its reference count hit zero, rather than
destroying itself. Then some other object (garbage collector) listening
for that message, could decide what to do with the it. I'm wondering
about whether TObject.Dispatch could achieve this.<br>
<blockquote cite="mid:004201cb8ba0$8c122a20$a4367e60$@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> </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 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<o:p></o:p></span></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>
<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>
</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>