[DUG] Usage - initialization and finalization

Karl Reynolds karlreynolds at xtra.co.nz
Tue May 23 11:33:45 NZST 2006


> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: winmail.dat
Type: application/ms-tnef
Size: 4536 bytes
Desc: not available
Url : http://ns3.123.co.nz/pipermail/delphi/attachments/20060522/1504db35/winmail-0001.bin


More information about the Delphi mailing list