Reputation: 11963
The following code is supposed to time out after a certain period, due to arrival of SIGALRM -
sub sig_alrm_handler() { die "Timed out, sorry" }
$SIG{ALRM} = \&sig_alrm_handler;
main();
Usually this approach works, except sometimes main() includes a Try::Tiny 'try' block which intercepts the "die" from sig_alrm_handler, effectively ignoring the timeout. How can this approach be changed so that SIGALRM will reliably terminate the program, even when main() catches exceptions?
Upvotes: 1
Views: 75
Reputation: 5129
If you want to end your program, you can call exit from your signal function. If you have an END block, it will still execute that.
Here's a code example. I used SIGINT
for it, but SIGALRM
works the same way.
#!/usr/bin/perl
use strict;
use warnings;
use Try::Tiny;
sub sig_int_handler() {
# die "Dying from SIGINT\n";
warn "Exiting from SIGINT\n";
exit(128 | 2); # 2 = SIGINT
};
$SIG{INT} = \&sig_int_handler;
my $i = 0;
try {
while (1) {
}
} catch {
print "caught exception\n";
};
print "continuing execution\n";
In this example, if you hit ctrl-c
while it is running, it will exit without printing the two print
statements. However if you uncomment the line with die
on it in the sig_int_handler
subroutine, it will print them both when you send the INT
signal.
Upvotes: 3