You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by "Russell D. Weiss" <rw...@inforelay.com> on 2000/04/04 08:00:02 UTC

Custom $SIG{__DIE__} problem (and "I'm glad to be back")

Hey guys,

Before I start with my problem / question, let me just say that I haven't
been subscribed for a while.  I was doing some heavy mod_perl development
last year, and I was subscribed to the list for a long time.  Eventually,
mail from this list and the other lists I was subscribed to got too great,
so I had to unsubscribe for a while.  I'm really happy to see that the list
is still alive... helping mod_perl developers.  I've consulted the Epigone
archive once or twice in my 'absence' :-).

I've also started on a consulting position for an Internet startup company,
and I've swayed them toward mod_perl!  We're in the process of developing a
very large application using mod_perl.  The only problem they've had is
finding other experience mod_perlers...  but there have been threads on the
list about that sort of thing.

Anyway, this may sound weird, but I have a "wrapper" object which contains
an Apache::Session object.  On odd cases, if a script dies, this object
never gets destroyed.  This seems to only occur in situations where the
script dies because the perl interpreter is pretty darn confused.  For
example, if I include a 'die "blah blah blah";' in the script, the "wrapper"
object does get destroyed, and thus the Session object gets destroyed /
untied.  In odd cases, however, like when the script contains a misplaced
quote or bracket, the object won't be destroyed.

As you may know, it's absolutely critical that the Apache::Session object
goes out of scope -- otherwise the lock on the object never goes away.  Then
we get a 'deadlock' and the Apache processes all get tied up waiting for
this lock to go away (which it never will).  The solution I've thought of is
to create a custom $SIG{'__DIE__'} handler.  By the way, this "wrapper"
object is also a toolbox, used commonly within most of our scripts (it
auto-constructs a Session, handles some of the dirtywork that
Apache::Session doesn't include [cookies, timeout, etc.], and includes other
objects that we often make use of, including CGI and HTML::Template).
Because almost every app uses this "wrapper" object, I'd like to have that
object include the custom die handler in the  object.  Also, this sighandler
needs to be able to run the DESTROY method on the object at hand, so we
undef the Session object (and some of the other objects) and release locks.

So, onto the problem.  Within the constructor for the wrapper object, I want
to do:
 bless $self, $class;
 $main::SIG{'__DIE__'} = $self->custom_die;

And this will work... BUT, as you may know, perl passes the error message as
the FIRST argument.  And, in perl's OO model, when I do the OO call as
above, $self is put into the first argument.  Unfortunately, perl doesn't
simply push the error onto the parameter array, instead it "overwrites" the
error message with the $self object reference.  I've tried different ways of
doing this.  The only way that "works" is a very kludgey way which I really
don't like, because it may cause me to run into errors later and it doesn't
really follow the OO model (a lexical to the package should know nothing
about object instances).

What I speak of is (within the constructor):
$WrapperObj::SelfRef = \$self;  # Very kludgey, I _hate_ this method
$main::SIG{'__DIE__'} = &custom_die;

This way, the custom_die sub does get the error message as the 0th element
in the param array... BUT it has to then do something like $self =
${$WrapperObj::SelfRef}; to get the object reference, so it can later do a
$self->DESTROY.  Messy, eh?

Any clues / hints as to how I can do this in a more correct / OO way.  My
goal here is to write a die sighandler that will allow me to explicitly
destroy this object and also output the error the browser (for developers)
rather than to the STDERR.

Thanks in advance,

Russ

Russell Weiss
Founder and Technical Manager
InfoRelay Online Systems, Inc.
http://www.InfoRelay.net/