By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,847 Members | 1,326 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,847 IT Pros & Developers. It's quick & easy.

Perl's DESTROY and Signal Handling

P: 11
I'm pretty new at this, and I'm trying to figure out how Perl's classes work with signals.
Specifically, it doesn't seem that a class's DESTROY function is called when you Ctrl-C the program.

I tried using
Expand|Select|Wrap|Line Numbers
  1. use sigtrap qw(handler DESTROY INT QUIT);
, but I'm not even sure this is the proper way to catch the signal. Either way, it seems I no longer receive a reference to my object when DESTROY is called. I keep getting this error:

Expand|Select|Wrap|Line Numbers
  1. Can't locate object method "time_passed" via package "INT" (perhaps you forgot to load "INT"?) at /var/local/bush/lib/ASH/Basic.pm line 113.
  2.  
Here is my DESTROY function:
Expand|Select|Wrap|Line Numbers
  1. sub DESTROY {
  2.     my $self = shift;
  3.  
  4.     my $runtime = time_passed(); 
  5.     print "Total run time: $runtime\n";
  6.  
  7.     close(ERR);
  8.     close(WARN);
  9.  
  10.     -d $self->{DIR}{THRESHOLD} ? print "All files saved to $self->{DIR}{THRESHOLD}.\n" : print "Self destroyed.\n";
  11.     die("done.\n\n");
  12. }
  13.  
Thanks for the help!
Feb 19 '08 #1
Share this Question
Share on Google+
6 Replies


KevinADC
Expert 2.5K+
P: 4,059
I'm pretty new at this, and I'm trying to figure out how Perl's classes work with signals.
Specifically, it doesn't seem that a class's DESTROY function is called when you Ctrl-C the program.

I tried using
Expand|Select|Wrap|Line Numbers
  1. use sigtrap qw(handler DESTROY INT QUIT);
, but I'm not even sure this is the proper way to catch the signal. Either way, it seems I no longer receive a reference to my object when DESTROY is called. I keep getting this error:

Expand|Select|Wrap|Line Numbers
  1. Can't locate object method "time_passed" via package "INT" (perhaps you forgot to load "INT"?) at /var/local/bush/lib/ASH/Basic.pm line 113.
  2.  
Here is my DESTROY function:
Expand|Select|Wrap|Line Numbers
  1. sub DESTROY {
  2.     my $self = shift;
  3.  
  4.     my $runtime = time_passed(); 
  5.     print "Total run time: $runtime\n";
  6.  
  7.     close(ERR);
  8.     close(WARN);
  9.  
  10.     -d $self->{DIR}{THRESHOLD} ? print "All files saved to $self->{DIR}{THRESHOLD}.\n" : print "Self destroyed.\n";
  11.     die("done.\n\n");
  12. }
  13.  
Thanks for the help!
Might be a question for perlmonks.com unless someone here understands whats happening by the description you have posted. Maybe you can't use DESTROY as a handler.
Feb 19 '08 #2

P: 11
So I figured out a round about solution. I eventually was able to get DESTROY called as the signal handler; however, this does not kill the program unless you have a
Expand|Select|Wrap|Line Numbers
  1. die()
or some other kill function inside the DESTROY function.

Obviously, this presents a small problem if you're through with your object before you're through with your script.

Here's somewhat of a solution:
Expand|Select|Wrap|Line Numbers
  1. use sigtrap qw(handler the_rest_is_silence INT QUIT);
  2. sub the_rest_is_silence { die(); } # Calling this on a kill signal ensures DESTROY is called
For some reason when this is in the .pm file, this works to help ensure DESTROY is called when you Ctrl+C. I don't really know why this is any different than not having it in there (since all you are doing is explicitly calling die() ), but it seems to work for me. Perhaps it is something to do with the Ctl+C signal vs. that sent from die().

Either way, if a class's DESTROY is not being called when the program is killed, this should help.
Mar 4 '08 #3

P: 1
Perl uses the %SIG hash to handle signals.. Not sure if this is wise.. DESTROY is for GC mostly.

however you can do
$SIG{TERM} = sub { $class->DESTROY() };

but again there is probably a better way to do it
Jul 20 '10 #4

Oralloy
Expert 100+
P: 983
I'm not going to reseach chapter and verse of the C-language and Posix specifications for signal handling, but they're good places to start your understanding.

Basically the Perl signal handling is the interpretive wrapping of the C-language signal handling mechanism.

EDIT:gahhhh - this may be wrong - you may have to retrieve the old handler from the %SIG hash yourself. My discussion is topical, I've done plenty of signal handling in C and C++, but nothing in Perl.

First off, when you register a new signal handler, Perl will hand you a link to the old one. This way you can save the link and chain to the old signal handler, so that behavioral integrity is maintained when a signal is recieved.

In your case, your handler can do all of its clean up and hand control to the handler that it replaced. That way, any modules besides yours, which are ctrl-C sensitive, can do their clean-ups, too.

Of course, the devil is in the details. If there will be multiple objects to DESTROY, you'll have to keep a list of them and make sure that they're all dealt with appropriately. Also, the list will have to be self-maintaining with weak references, so if an object is released it will be DESTROYED appropriately by the system and removed from the list....

Implementation gets ugly and I'm not entirely sure of the necessary implementation details. If you simply keep a list of objects, then DESTROY will never be called, because they will always be referenced. Thus the requirement for a list of weak references.

What it really comes down to is the level of robustness and reliability you require. Only you can answer that.

Good luck.
Jul 21 '10 #5

100+
P: 115
from what I perceive is that you have to embed a kill function within a destroy signal
Jul 24 '10 #6

P: 45
@Jyoti Ballabh
do u have embedding function? if yea, care to share?
Jul 25 '10 #7

Post your reply

Sign in to post your reply or Sign up for a free account.