dimecadmium has asked for the wisdom of the Perl Monks concerning the following question:

I'm making an IRC bot. I'm using alarm (for now?) to make it check the request queues.

I have no clue why/how, but when I run the code (which calls the sub, Alrm, manually once at startup) it works fine until the alarm next expires (and it works fine if I 'kill "ALRM", $$').

I've tried using Time::HiRes (setitimer, alarm) and Perl's core alarm, and I've made sure there's no sleeps or anything else in my code, just in case. I've tried with return 1 and 0.

I've narrowed it down to the sub ending, using prints.

Code:

sub Alrm { &M(0, $cfg->{staff}, "Received SIGALRM."); my $sth1 = $dbh->prepare('SELECT COUNT(*) FROM rand_reqs WHERE + acted = 0'); $sth1->execute(); my @ary = $sth1->fetchrow_array(); my $reqs = $ary[0]; if ($reqs) { &M(0, $cfg->{home}, "There are $reqs requests in-queue +."); &M(0, $cfg->{staff}, "CHECK QUEUE."); } $SIG{ALRM} = \&Alrm; alarm(30); }

Replies are listed 'Best First'.
Re: alarm() killing my program
by sflitman (Hermit) on Jan 24, 2009 at 01:49 UTC
    I am not certain that's the best way to use alarm. Typically, people set the $SIG{ALRM} handler to a sub which throws an exception, then the main body of code is in an eval so the alarm gets trapped properly. Also, use local so you don't lose library definitions of alarm handler.
    sub poll { # execute code with timeout eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm 30; # alarm in 30 seconds # your code here (could timeout) alarm 0; # cancel alarm }; if ($@) { die $@ unless $@ eq "alarm\n"; # propagate unexpected errors # take action for timeout } }