in reply to Re: Closures, object destruction and memory leaks
in thread Closures, object destruction and memory leaks

Thanks all - the target platform is perl 5.6+, so I guess the bug tilly mentioned won't be an issue. I've got this working the way I want now (well - the way I want for an alpha relase :-)) and I've decided on the following:
sub execute { my $self = shift; my $req = BigHairyDatabaseInteraction->new(...); { local $SIG{INT} = sub {$req->{_signal} = 2; $req->handleInterrupt; }; local $SIG{TERM} = sub {$req->{_signal} = 15; $req->handleInterrupt; }; $req->executeRequest(); } # If a TERM/INT signal has been delivered during the request # then pass it on to the program itself: if($req->{_signal}) { kill $req->{_signal}, $$; } ... rest of $sth->execute()
The idea is that I want to override any signal handlers that the calling program may have installed so that I can interrupt the processing on the server as needed, but I also want to make sure that the caller does eventually receive the signal.

So far this appears to work really well...

Michael

Replies are listed 'Best First'.
Re: Re: Re: Closures, object destruction and memory leaks
by tilly (Archbishop) on Nov 11, 2003 at 01:54 UTC
    One tip that may make sense.

    Before you do the local, capture the existing handlers in lexical variables and pass them in to $req's handleInterrupt method.

    That way if a particular request type wants to, it can rethrow an exception properly up the chain, rather than just ignoring the poor programmer who is trying to put a signal handler around your code because they really don't want to exit on that signal.

    Doing this makes the signal handler system act a little bit more like a proper exception handling system. Not that much more like, mind you, but somewhat more like it.

      Hmm - that was why I have the
      if($req->{_signal}) { kill $req->{_signal}, $$; }
      bit. That re-delivers the signal to the program, rather than chaining the handlers, but won't that achieve the same end-result?

      In any case the $req->handleInterrupt() call really only sets a flag in the $req object, so chaining the signal handlers here would potentially prevent the request from being properly cancelled on the server, which I think could be a problem.

      Michael

        If your signal handler doesn't do much, then that is probably the right way to do things. And on reflection, having signal handlers not do much is generally the right way to do things.

        My thinking was in case your signal handler did something irrevokable like try to exit, in which case you should allow people to catch it. But if you don't, then don't worry about it. :-)