END blocks and fork

M

Matthew Braid

[Note: I accidentally posted this in comp.lang.perl.tk. This is a repost
in a more appropriate group.]

Hi all,

First off - where in the docs is the information on BEGIN/END/INIT/etc
blocks? I've just spent a rather frustrating 30 mins or so trying to
find them. No doubt its somewhere obvious that I've missed, but still....

Anyway.

Is there a standard way of disabling END block evaluation? The problem
I'm having is that I've discovered that a package I'm using does a
fork/exec. Normally this is ok, but if the exec fails it then does a
CORE::exit to make sure the child ends. This triggers any END blocks
that were defined in the parent when they really shouldn't be firing.

I know I can get around it with something like:

BEGIN {
my $processid = $$;
END {
if ($$ == $processid) {
# DO STUFF
}
}
}

but I didn't realise that a package I was using was failing a forked
exec, so it took me a lot of very annoying debugging to discover what
the problem was.

Is there a way to tell perl to only run END blocks that were defined in
the current process (ie forked children only run END blocks that have
been defined after the fork)? Or a way of temporarily disabling END blocks?

It just seems like a nasty gotcha that has a very consistant (but quite
ugly) workaround.

MB
 
K

Keith Keller

First off - where in the docs is the information on BEGIN/END/INIT/etc
blocks? I've just spent a rather frustrating 30 mins or so trying to
find them. No doubt its somewhere obvious that I've missed, but still....

It's not in an obvious place: perldoc perlmod
Is there a standard way of disabling END block evaluation? The problem
I'm having is that I've discovered that a package I'm using does a
fork/exec. Normally this is ok, but if the exec fails it then does a
CORE::exit to make sure the child ends. This triggers any END blocks
that were defined in the parent when they really shouldn't be firing.

Unfortunately for you, perldoc perlmod seems to imply that END blocks
are not disabl-able. It mentions that END blocks run even under die(),
but does talk briefly about signals. You might want to see if something
like that will work for you.

You might also try looking at $? in your END blocks, but that may end up
being unmanageable.

--keith
 
A

Anno Siegel

Matthew Braid said:
[Note: I accidentally posted this in comp.lang.perl.tk. This is a repost
in a more appropriate group.]

Hi all,

First off - where in the docs is the information on BEGIN/END/INIT/etc
blocks? I've just spent a rather frustrating 30 mins or so trying to
find them. No doubt its somewhere obvious that I've missed, but still....

Anyway.

Is there a standard way of disabling END block evaluation? The problem
I'm having is that I've discovered that a package I'm using does a
fork/exec. Normally this is ok, but if the exec fails it then does a
CORE::exit to make sure the child ends. This triggers any END blocks
that were defined in the parent when they really shouldn't be firing.

Well... you don't want them to. The basic behavior (running an END block
in all processes) is correct.
I know I can get around it with something like:

BEGIN {
my $processid = $$;
END {
if ($$ == $processid) {
# DO STUFF
}
}
}

That's what I have done in similar cases. For a little optical improvement

use constant PPID => $$;
# ...
END {
return unless $$ == PPID;
# ...
}

If you can control how the kid process exits (that doesn't seem to be
the case, but I'm mentioning it anyway) you can use POSIX::_exit, which
bypasses END.

Another possibility is to establish the END block only after the
kid has been forked. The END block is established at compile time,
so this either means forking in a BEGIN block (quite possible, but
often impractical), or setting up the END block in a string eval

eval "END { ... }";

after the fork.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,458
Latest member
Chris#

Latest Threads

Top