use Sys::AlarmCall;
#open socket
#....
&socket_read();
sub alarm_signal {
print STDERR "Received alarm\n";
&socket_read();
};
sub socket_read {
while(1){
alarm_call(60, 'alarm_signal');
my $len = $socket->sysread($line,1024);
#.....
}
}
The function passed to alarm_call is not called on timeout as you expect. The function passed to alarm_call is the one alarm_call will interupt after the specified timeout. Reread the [mod://Sys::AlarmCall|docs].
sub socket_read {
my $len;
{
($len, my $errmsg) = alarm_call(60, '->sysread', $socket, $line, 1024);
if (defined($len)) {
if ($len eq 'TIMEOUT') {
print STDERR "Received alarm\n";
redo;
}
if ($len eq 'ERROR') {
die($errmsg);
}
}
}
...
}
Of course, you could also use [doc://alarm|alarm] directly.
sub socket_read {
my $len;
{
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm 60;
$len = $socket->sysread($line, 1024);
};
alarm 0;
if (my $e = $@) {
if ($e eq "alarm\n") {
print STDERR "Received alarm\n";
redo;
}
die($e);
}
}
...
}
Untested.
Update: Added second snippet. Handle exceptions.
Either use IO::Select or the second form from perldoc -f select
It's also much simpler. Why didn't I think of that?
use IO::Select ();
sub socket_read {
my $sel = IO::Select->new($socket);
while (!$sel->can_read(60)) {
print STDERR "Received alarm\n";
}
my $len = $socket->sysread($line, 1024);
...
}
Reference: [mod://IO::Select]
-sam
perlmonks.org content © perlmonks.org and ikegami, InfiniteLoop, ozone, samtregar
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03