Perl's DESTROY and Signal Handling

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • muppetjones
    New Member
    • Feb 2008
    • 11

    Perl's DESTROY and Signal Handling

    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
    Code:
    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:

    Code:
    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.
    Here is my DESTROY function:
    [CODE=perl]
    sub DESTROY {
    my $self = shift;

    my $runtime = time_passed();
    print "Total run time: $runtime\n";

    close(ERR);
    close(WARN);

    -d $self->{DIR}{THRESHOL D} ? print "All files saved to $self->{DIR}{THRESHOL D}.\n" : print "Self destroyed.\n";
    die("done.\n\n" );
    }
    [/CODE]

    Thanks for the help!
  • KevinADC
    Recognized Expert Specialist
    • Jan 2007
    • 4092

    #2
    Originally posted by muppetjones
    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
    Code:
    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:

    Code:
    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.
    Here is my DESTROY function:
    [CODE=perl]
    sub DESTROY {
    my $self = shift;

    my $runtime = time_passed();
    print "Total run time: $runtime\n";

    close(ERR);
    close(WARN);

    -d $self->{DIR}{THRESHOL D} ? print "All files saved to $self->{DIR}{THRESHOL D}.\n" : print "Self destroyed.\n";
    die("done.\n\n" );
    }
    [/CODE]

    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.

    Comment

    • muppetjones
      New Member
      • Feb 2008
      • 11

      #3
      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
      Code:
      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:
      [CODE=perl]use sigtrap qw(handler the_rest_is_sil ence INT QUIT);
      sub the_rest_is_sil ence { die(); } # Calling this on a kill signal ensures DESTROY is called[/CODE]
      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.

      Comment

      • See Furst
        New Member
        • Jul 2010
        • 1

        #4
        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

        Comment

        • Oralloy
          Recognized Expert Contributor
          • Jun 2010
          • 988

          #5
          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.
          Last edited by Oralloy; Jul 21 '10, 12:28 AM. Reason: Needed to acknowledge limits of personal working experience.

          Comment

          • Jyoti Ballabh
            Banned
            New Member
            • Jul 2010
            • 115

            #6
            from what I perceive is that you have to embed a kill function within a destroy signal

            Comment

            • iohos
              Banned
              New Member
              • Jul 2010
              • 45

              #7
              Originally posted by Jyoti Ballabh
              from what I perceive is that you have to embed a kill function within a destroy signal
              do u have embedding function? if yea, care to share?

              Comment

              Working...