[DUG] Usage - initialization and finalization
Todd Martin
toddm at kol.co.nz
Tue May 23 13:57:06 NZST 2006
Hi Karl
I think there are two possibilities here.
a) the singleton object is no longer needed, once finalization of the
application begins.
In this case you can free the singleton in the finalization section and set
it to nil. Then have the accessor method (I assume you use an accessor
method) check whether the singleton is nil, before attempting to use it. eg
function DoSomething(AObject : TObject);
begin
if assigned(SingletonInstance) then
begin
SingletonInstance.DoSomething(AObject);
end;
end;
finalisation
FreeAndNil(SingletonInstance);
b) the singleton object is needed until the absolute last object (that uses
it) is destroyed.
If you can resolve this problem with a reference counting interface, then
another option would be to build your own reference counting solution.
Create a list inside your singleton which adds each object as it is
processed (during initialization/runtime) and removes each object as it is
processed (during finalization). Then when the list count gets to zero, the
singleton frees itself.
Todd.
----- Original Message -----
From: "Karl Reynolds" <karlreynolds at xtra.co.nz>
To: "'NZ Borland Developers Group - Delphi List'" <delphi at ns3.123.co.nz>
Sent: Tuesday, May 23, 2006 11:33 AM
Subject: RE: [DUG] Usage - initialization and finalization
> > Sorry if you felt I was patronizing you, but why would I
> > waste my energy
> > doing that to anyone. If patronizing was my goal, I just
> > wouldn't reply
> > to a post... That's patronizing.
> >
> > It was a serious question. And now that you link to a post you were
> > referring to, that you didn't link to before, I have my
> > answer don't I?
>
> Well, patronizing is perhaps the wrong word... what do you call it when
> someone misunderstands what you say, tells you that there's no such thing
as
> the term you used (a circular reference) and then explains the completely
> obvious to you? :-) And then there was the quoting of sections of the
> manual in the previous post. Ok, I admit it, I need to grow a thicker
skin.
> I was trying to express the term "frustrating", if I could come up with
the
> right context in which to use it. As for that link, I only dug up a
> reference to reduce the likelihood that I was going to get a knee-jerk
> reply... ahem.
>
> I am admittedly in a sour mood because yesterday was a complete waste of a
> day for me. I discovered the hard way the D6 DBExpress bug where closing
a
> query does not commit the internal metadata transaction (examine
> SQLConnection.ActiveTransactions before you create run your query and
after
> you commit it and you'll see what I mean). So I have to break the
> connection every time before running DDL statements - ugh. And it just
adds
> poison to the wound that they bothered to fix this in a D7 update, but
> didn't think D6 deserved the same.
>
> > I would say that Peter is wrong. You can determine what is implemented
> > first through analysis. The level of difficulty of doing so is really
> > dependant on the skill of the person looking at the code. His comments
> > regarding implemetaion Uses clauses is tripe.
> >
> > If you could impose order, which you can by cheating, then it would
> > defeat the purpose of initialization which is "to prepare a
> > unit of code
> > for use before any other unit requiring that unit is initialized"
> >
> > If unita reffered to unitb in implementation, and unitb also did the
> > same, then somewhere in the project something must refer to
> > either unita
> > or unitb, causing the correct initialization phase.
>
> You are arguing from a purely theoretical standpoint. You obviously
haven't
> encountered the problem where you have mutually referencing units in a
> project initializing in the wrong order (and as an aside note, even when
one
> is using the other in the interface section this can happen, because it
> depends on the order of reference assembled by other units), and while
> rearranging the position of those units in the dpr makes NO difference,
the
> ordering of other units in the dpr makes the initialization and
finalization
> order change. Until the next time the project changes, when by chance the
> intialization/finalization order of the offending units can reverse again,
> and once again random AVs on program exit appear.
>
> Shurely others have encountered this problem?
>
> To clarify the issue further, the singleton I was referring to in my
> original post is one whose methods are often used within the destructors
of
> components which reside on forms. These destructors will not run until
the
> forms are destroyed, which may not happen until the finalization of
> forms.pas. So my singleton needs to still exist during the finalization
of
> the forms unit, at a bare minimum. So, either the singleton's unit's
> finalization (in which the singleton is released) has to occur after the
> finalization of forms.pas or the singletons's finalization has to be
handled
> in a different way.
>
> And before anyone suggests it, if I don't free it at all then it leaves
some
> global resources locked.
>
> Ok, I'm willing to accept that if you traverse your usage tree completely
> (assuming we are including the usage tree of the delphi units as well -
lets
> hope you have the source), then you *may* be able to come up with an order
> of used units which will cause your initializations, and consequently
> finalizations, to fire in exactly the order that you want them to. I just
> remain to be convinced that it's practical for me to come up with a new
> order every time something changes when I have fifty projects and a
thousand
> units (not counting the delphi source units) to go through, and when I
only
> discover that the problem has recurred once the AVs start up. Even if I
> come up with a correct order, it's still going to be an accident waiting
to
> happen as long as I have any mutually referencing units with
initializations
> or finalizations that must be run in a particular order.
>
> Having said that, the units do need a cleanup in that too much crap is
> linked into some projects that shouldn't be. Cleaning out unnecessary
> references, and merging or dividing units to faciliate that, would
simplify
> things. It wouldn't fix the core problem though.
>
> So, back to my original question, slightly rephrased, and mostly intended
> for those who have run into this before:
>
> Taking it as a given that you can't rely on the finalization order of
units,
> if you have a "singleton" object that needs to be used, directly or
> indirectly, in the finalization of other units than the one in which it is
> declared, what do people do to handle that object's cleanup? Do it using
> interfaces and reference counting auto-cleanup (which is what I was driven
> to do in the end), or is there a better way?
>
> Cheers,
> Carl
>
----------------------------------------------------------------------------
----
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
>
----------------------------------------------------------------------------
----
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.1.392 / Virus Database: 268.7.0/345 - Release Date: 22/05/2006
--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.392 / Virus Database: 268.7.0/345 - Release Date: 22/05/2006
More information about the Delphi
mailing list