Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Need Help With Alarm And Eval

by PerlRocks6345 (Novice)
on Dec 06, 2012 at 12:04 UTC ( #1007553=perlquestion: print w/ replies, xml ) Need Help??
PerlRocks6345 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks the code below works perfectly

use strict; my $errorName="alarm\n"; my $time=5; eval { local $SIG{ALRM} = sub { die "$errorName" }; alarm $time; sleep(10); }; my $error= $@; Off($error,$errorName); sub Off{ my $error=$_[0]; my $errorName=$_[1]; if( $error && $error eq "$errorName") { warn "Timed out!!!\n"; exit ; } else { alarm 0; print " you can continue"; } }

But when I make it to subroutines as this

use strict; my $errorName="alarm\n"; my $time=5; eval { On($time,$errorName); #dostuff(); sleep(10); }; my $error= $@; print "error ".$error."error \n"; Off($error,$errorName); sub On { my $time=$_[0]; my $errorName=$_[1]; local $SIG{ALRM} = sub { die "$errorName" }; alarm $time; } sub Off { my $error=$_[0]; my $errorName=$_[1]; if( $error && $error eq "$errorName") { warn "Timed out!!!\n"; exit ; } else { alarm 0; print " you can continue"; } }

It does not work as expected instead of throwing the warning message it throws "Terminating on signal SIGALRM(14)" Need your help Monks.Thank you in advance

Replies are listed 'Best First'.
Re: Need Help With Alarm And Eval
by afoken (Monsignor) on Dec 06, 2012 at 12:12 UTC

    The problem is local inside sub On. Perl restores $SIG{'ALRM'} as soon as On returns. You have no other handler for that signal, so the default handler kicks in and kills perl.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Hey thanks a lot for your reply removed local and every thing worked perfectly!!!! Thanks a lot!!!!!

        removed local and every thing worked perfectly

        No, it doesn't. The On function sets the signal handler globally, for ever, even after eval has finished. You want local $SIG{'ALRM'} inside that eval.

        The extra subs don't make your code any clearer. I think you should keep alarm and local $SIG{'ALRM'} inside the eval.

        You could also consider writing a generic timeout function like this:

        # untested sub withTimeout { my ($timeout,$worker,$timeouthandler)=@_; eval { local $SIG{'ALRM'}=sub { die "TIMEOUT" }; alarm($timeout); $worker->(); alarm(0); }; if ($@ and $@=~/TIMEOUT/) { $errorhandler->(); } }

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1007553]
Approved by Athanasius
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (13)
As of 2016-06-28 16:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred method of making French fries (chips) is in a ...











    Results (359 votes). Check out past polls.