LINUX.ORG.RU

Загадка с SIGPIPE/Unix_exception (EPIPE) в OCaml.


0

0

Добрый день.

background: есть самописный демон на OCaml. Слушает (select) сокет, отвечает на запросы. Раз в 10 минут сбрасывает резултьтаты работы в файл, что занимает порядка единиц секунд для миллиона записей.

Так вот, с этим и связана проблема: если во время этой операции подловить демона и сделать что-то типа
$ echo "status" | socat - UNIX-CONNECT:/path/to/socket

то демон
дописывает файл дампа,
возвращается на обработку реквестов,
получает из socket backlog'а коннект,
читает из него команду,
обрабатывает,
и пытается отправить ответ обратно. 

Но к этому моменту он уже опоздал, клиентский коннект уже отвалился. И демон гибнет от SIGPIPE.

Это не проблема для "настоящих" клиентов, которые _всегда_ ждут ответа и не отваливаются пока его не получат. Но при помощи echo и socat демона можно при достаточном упорстве свалить, просто дождавшись момента сброса дампа.

Так вот, самое странное что конструкция
try 
    Unix.send client str 0 (String.length str) [] 
with 
    Unix_error (EPIPE,_,_) -> ()

Не отрабатывает. Не отрабатывает даже

with
    _ -> ()

Т.е. очевидно не происходит возбуждения эксепшена, а сразу прилетает сигнал.
Выход из ситуации очевиден -- устанавливать обработчик сигнала SIGPIPE вокруг данного фрагмента кода в ignore, но как-то это странно.

Сталкивался ли кто-то из уважаемого собрания с чем-то подобным? И ошибка ли это в OCaml или так положено?
★★☆☆

Это явный глюк. Все остальные юниксовые исключения ловятся.

anonymous
()

а помоемому так и положено. насколько я понимаю то ловить сигналы - это не задача исключений.

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