In order to promptly respond to signals while still freeing outstanding resources, I do something like this:
The problem is that Bad Things happen if a signal arrives inside a DESTROY method. (Because some of my resources can take seconds to free, this happens a lot in practice.) The issue is that (at least in Perl 5.6.1 and 5.8.2) a die inside a destructor terminates the destructor, but it does not propagate further. For example:eval { local $SIG{INT} = sub { die "SIGINT\n" }; # Do all the resource allocation and work here. # All the resources have gone out of scope by the # end of this block. } if($@) { kill 'INT', $$ if $@ eq "SIGINT\n"; die $@; }
prints:sub DESTROY { print "DESTROY\n"; die; print "HUH\n"; } { my $x = bless []; } print "DONE\n";
This is understandable, because having your DESTROY methods die is fundamentally flawed (http://www.gotw.ca/gotw/047.htm). However, while it's possibly OK to leave the present object's resource behind, I still want all the other objects DESTROY'ed and the program to terminate immediately thereafter.DESTROY DONE
It seems to me that what's needed here is a way to defer signals until we are no longer inside a destructor, or at least a way for destructors to re-raise them without having them take effect while still in the destructor. I could do that by implementing deferred handling in Perl (as an additional layer over the existing deferred handling in the Perl 5.8 core), but OMFG that's ugly and fragile.
I can't believe that I'm the first person to run into this. What's the Right Way to deal with it?
&ers
In reply to Propagating a Signal from DESTROY by topnerd
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |