Subject: | get_ntp_response() hangs on Windows systems |
Net::NTP version 1.2
Show quoted text
> perl -v
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 18 registered patches, see perl -V for more detail)
Copyright 1987-2007, Larry Wall
Binary build 822 [280952] provided by ActiveState http://www.ActiveState.com
Built Jul 31 2007 19:34:48
Perl may be copied only under the terms of either the Artistic License
or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
------------------------------------
OS: Windows XP SP3
Problem description:
Calls to get_ntp_response() hang on Windows systems when no response is
received from specified NTP server.
This is due to the use of alarm()/$SIG{ALRM} to timeout recv() calls.
Apparently, recv() cannot be interrupted by $SIG{ALRM} on Windows.
Here is the work around I have implemented which I believe is platform
independent. Note also that I also don't die on failure but instead,
return an empty list to the caller to indicate a failure.
Section of code from get_ntp_respons() follows (commented out) followed
by my suggested replacement code:
# eval{
# local $SIG{ALRM} = sub { warn "Net::NTP timed out geting NTP
packet\n"; exit;};
# alarm(5);
# $sock->recv($data,960)
# or die "recv() failed: $!\n";
# alarm(0);
# };
#
# if($@){
# die "$@";
# }
# replacement for the above code follows
my $rin = '';
vec($rin,$sock->fileno(),1) = 1 ;
my $rout = $rin;
select($rout,undef,undef,$TIMEOUT) ;
if (vec($rout,$sock->fileno(),1)) {
$sock->recv($data,960)
or die "recv() failed: $!\n";
}
else {
warn "Net::NTP timed out geting NTP packet\n" ;
return();
}
- Mark Ginsburg