Запись пустых данных в неблокирующий сокет приводит к зависанию epoll_wait - PullRequest
0 голосов
/ 02 июня 2018

Итак ... Я был очень озадачен тем, почему мой tcp-сервер на основе epoll случайным образом зависал epoll_wait, а затем отправлял пустой массив некоторым соединениям, когда я завершал работу с SIGINT.

ОказываетсяУ меня была случайная ошибка в моем программном обеспечении, в результате которой я написал следующее:

write(server_socket_fd, payload, 0)

Хотя это было неверно, я, конечно, не ожидал, что вызов write с размером 0 зависнетвсе это.

Почему происходит такое поведение и как мне его предотвратить?Вызывает запись с аргументом длины ноль только UB, и я всегда должен убедиться, что размер> 0?

1 Ответ

0 голосов
/ 02 июня 2018

Отвечая на ваши вопросы в обратном порядке,

Вызывает запись с аргументом длины ноль только UB, и я всегда должен убедиться, что размер> 0?

Согласно POSIX ,

Если nbyte равен нулю, а файл не является обычным файлом, результаты не определены.

Linuxстраницы руководства для write() говорят то же самое.«Unspecified» отличается от «undefined» в стандарте, но если вы действительно заботитесь о том, что происходит, то разумно также избегать неопределенного поведения.

Почему происходит такое поведение и как его предотвратить?

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

...