LINUX.ORG.RU

libpcap


0

0

Есть простая программа, которая проверяет наличие dhcp серверов в сети (что-то вроде пинга).

написана с использованием сабжа. И вот такой в ней косяк. Если во время работы программы выдернуть сетевой кабель, то она зависает в вызове recvfrom, и игнорирует все сигналы кроме KILL, хотя в ней самой естественно предусмотрен таймер (на SIGALRM), и по идее она не должна ожидать пакета более 1 секунды..

Есть идея заменить таймер на sigalarm с помощью select, просто с поверх Libpcap используется некая обертка с которой это сделать не очень удобно.

В чем может быть проблема и как этого избежать, кстати я подозреваю что этим страдают почти все программы использующие сабж.

★★★★

перед recvfrom() заблокировать SIGALRM
создать отдельный поток
выполняющий цикл

for (;;) {
alarm(1);
pause()
if (time(NULL) - last > LIMIT)
exit_group(0);
}

last - volatile переменная
после каждго успешного recvfrom(), процесс устанавливает ее значение посредством вызова time(NULL)

rei3er
()
Ответ на: комментарий от rei3er

Мне не нужно выходить по таймауту, мне нужно потом еще кое что сделать, собрать статистику например.. Если из второго потока отправить alarm в поток где спит recvfrom, он проснется? Из консоли-то процесс инорирует все кроме KILL.. Да и вообще не хочется в такую простую программу пихать потоки..

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

Хотя конечно статистику можно собрать во втором потоке, но все равно пихать в пинг потоки это уже черезчур.. Кстати обычный (icmp) ping не виснет, а возвращает Network Unreachble. надо посмотреть его код, может что ясно станет 8))

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

> Из консоли-то процесс инорирует все кроме KILL
если он реагирует на SIGKILL, значит он не находится в состоянии TASK_UNINTERRUPTIBLE
тогда единственная возможная причина отсутствия реакции на сигналы - блокировка всех сигналов
здесь всего два решения: дополнительный поток или poll/select/epoll

rei3er
()
Ответ на: комментарий от rei3er

Вот и прикол в том что никаких блокировок не вызывается. Просто вытаскивается кабель и все. Статус у него просто Sleep. Надо будет попробовать select. Боюсь, как бы он тоже не завис.

Интересно было бы узнать причину этого. Нигде в манах о recvfrom ничего подобного не нашел 8(

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

> Вот и прикол в том что никаких блокировок не вызывается
блокировка сигналов может быть в ядре во время выполнения recvfrom()

rei3er
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.