Проверьте, что write () / send () может обрабатывать весь буфер без блока, в противном случае не работает (частичной записи нет) - PullRequest
4 голосов
/ 22 июля 2011

Я использую соединение SOCK_SEQPACKET, и для меня очень важно, чтобы весь буфер отправлялся одним вызовом write () / send ().Я также работаю с драйвером устройства, который предназначен для обработки всего блока данных за один вызов.В то же время я хочу обработать ситуацию, когда write () / send () блокируется из-за переполнения буфера, т.е. я хочу получить обратную связь, если текущая реализация получает узкое место здесь.Я работаю с glibc, Linux 2.6.

Мне нужно реализовать метод, который принимает буфер, и он либо отправляет буфер полностью, либо указывает на сбой из-за блокировки (т. Е. Переполнение системного буфера).

Похоже, использование send (..., MSG_DONTWAIT) / fcntl (..., O_NONBLOCK) не является решением, так как они принимают частичную запись до сообщения EWOULDBLOCK / EAGAIN.Есть ли способ проверить, достаточно ли места в исходящем буфере или есть специальный метод для записи или полного сбоя?

В качестве альтернативы, можно ли обнаружить блок другими способами?Например, таймер + сигнал, кажется, вариант, но мне не нравится идея устанавливать его для каждой записи.

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 25 июля 2011

Эксперимент показывает, что частичная отправка не происходит в моей установке (glibc 2.11.1, ядро ​​2.6.32-29) и что EAGAIN / EWOULDBLOCK возвращается send (... MSG_DONTWAIT), как и ожидалось для сокета AF_UNIX + SOL_SEQPACKET.

Не уверен, универсально ли поведение.

0 голосов
/ 22 июля 2011

Чтение значения SO_SNDLOWAT на сокете даст вам подсказку о размерах сообщений, которые могут быть отправлены без риска частичной отправки.

...