Виснет на $sock->recv. Perl под Windows.

DenisPerm

New member
27.06.2008
2
0
#1
Не работает вот такая конструкция:

eval{
local $SIG{ALRM} = sub { die "Net::NTP timed out geting NTP packet\n"; };
alarm($TIMEOUT);
$sock->recv($data,960) or die "recv() failed: $!\n";
alarm(0)
};

Если идет обращение к несуществующему хосту, то виснет на $sock->recv.
Если ответ от хоста есть, то все нормально.

В чем дело и как правильно это реализуется ?
 

DenisPerm

New member
27.06.2008
2
0
#3
Нее. Винда точно XP.
Да и сама конструкция alarm работает.
Т. е. если $sock->recv заменить на sleep,
то alarm через TIMEOUT работает.

Виснет именно $sock->recv.

И я ХЗ что с этим делать.
Самый смех, что текст их модуля Net-NTP.
И модулю то 300 лет.
 
V

Vovochka

#4
Хех :)
Может вместо эвала попробовать в поток обернуть?
Хотя вряд ли оно того стоит.
 
04.09.2006
2 566
3
#5
Слабо представляю что делает ваш код на Перле, но все же...
В MSDN (Winsocks v.2) по поводу recv сказано:
If no incoming data is available at the socket, the recv call blocks and waits for data
Т.е. будет висеть пока не пойдут данные.
 
V

Vovochka

#6
В том то и прикол. Этот хак (код) помогает избавиться от блокировки:
Код:
local $SIG{ALRM} = sub { die "Net::NTP timed out geting NTP packet\n"; };
Присваиваем обработчик для сигнала SIGALART
С этим обработчиком при получении сигнала программа должна "умереть", но так как этот участок кода завернут в eval, то просто мы выпадем из этого блока.
Код:
alarm($TIMEOUT);
Заказываем SIGALARM через $TIMEOUT сек.
Код:
$sock->recv($data,960) or die "recv() failed: $!\n";
Блокирующий вызов.
Код:
alarm(0);
Мы не выпали из блока, значит блокирующий вызов завершился. Отказываемся от заказа на SIGALARM
Вот такая вот ботва :)