On Tue, Aug 27, 2002 at 01:23:50PM -0700, Sean O'Rourke wrote:
> On Tue, 27 Aug 2002, Mike Lambert wrote:
> > Is there still a need for determinstic destruction, even in light of the
> > alternative approaches mentioned above?
> 
> Yes, if the destruction of the resource is itself important to the
> program.  For example, one way to do exception-safe locks in C++ is to
> have a stack-allocated object whose constructor acquires the lock, and
> whose destructor unlocks it.  I'm not sure if this is a paradigm we want
> to support, but it's something to think about.

On a very similar note, I've used them for logging timing statistics.
Something like

sub processRequest {
        my $timer = Timer->start("query");
}

would produce

 <timestamp> START query
 <timestamp> STOP query, 0.26 seconds elapsed

no matter how processRequest exited.

I have done various other similar things. Someone (Abigail?) wrote a
CPAN module to do arbitrary actions this way; we could check with her
to figure out what they're useful for.

So we've identified two general (overlapping) classes of uses: those
that are purely scope-related (and can be implemented with a stack),
and those that are used to control allocation of a scarce resource,
like file descriptors (or memory!).

The first, stack ops, could be implemented by making it illegal to
keep external references to those objects, and then just checking them
at either every scope exit, or at points manually inserted by the
compiler. Or maybe a hybrid is possible -- you can keep an external
reference, but you lose the guarantee of prompt finalization if you do
so. I haven't thought that one through.

The second, scarce resource management, can be handled the same way as
regular memory garbage collection: only check on allocations, and only
when you're in danger of using too much.

Although many of the examples of this sort of use bother me, for one
reason -- what happens if the destruction fails? free() won't, but
close() often will, and finalization might happen far from code that
could handle the failure properly.

Could we maybe keep a continuation in these objects, and throw the
exception from there? (Does that even make sense? My brain hurts.) It
could easily be too late by then, anyway, and maybe the answer is just
"if you need to handle finalization failure, then do it explicitly!"

Reply via email to