LINUX.ORG.RU

EPOLL и детект будущего EWOULDBLOCK


0

2

С одной стороны, man epoll, A9:

For  stream-oriented  files  (e.g.,  pipe,  FIFO,   stream
socket),  the  condition  that the read/write I/O space is
exhausted can also be detected by checking the  amount  of
data  read  from  / written to the target file descriptor.
For example, if you call read(2) by asking to read a  cer‐
tain  amount of data and read(2) returns a lower number of
bytes, you can be sure of having exhausted  the  read  I/O
space  for  the  file  descriptor.   The same is true when
writing using write(2).  (Avoid this latter  technique  if
you  cannot  guarantee  that the monitored file descriptor
always refers to a stream-oriented file.)
А с другой, man write:
If  a  write()  is  interrupted by a signal handler before any
bytes are written, then the call fails with the  error  EINTR;
if it is interrupted after at least one byte has been written,
the call succeeds, and returns the number of bytes written.

Получается, что я не могу надёжно использовать технологию в A9, например, с пайпами? plain file является stream-oriented? а файл с O_APPEND? send() и splice() ничего не говорит насчёт поведения в случае когда и послать-то послал, и сигнал-то пришёл. Как быть? кому доверять?

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

UPD. send() косвенно говорит, что EINTR придёт только если совсем ничего не послал. а вот splice() не говорит....



Последнее исправление: mmarkk (всего исправлений: 1)

Про write: так вызывай его столько раз, пока он не вернет 0. положительные значения возможно дают EINTR, а 0 однозначен.

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

В этом и фича - не вызывать лишний раз сисколл если доподлинно известно что он вернет EWOULDBLOCK. об этом и говорит первая цитата. Речь идёт о мегаацкопроизводительной проге, в которой экономится каждый сисколл.

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

Что такое plain - файл дисковой ФС? Тогда нет

я твой дом труба шатал

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

это я и сам допетрил. однако жt явно (как у write) у них не сказано. к тому же список возможных еррно никогда в линуксе не был исчерпывающим. в вдруг, сплайс возвращает любые другие еррно свзанные с пайпом или c той операцией которую он делает (recv, read, send, write)?

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

а вдруг, сплайс возвращает любые другие еррно свзанные с пайпом или c той операцией которую он делает (recv, read, send, write)?

Скачай с kernel.org софтинку и погляди, что там оно может возвращать.

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

>> Что такое plain - файл дисковой ФС? Тогда нет

я твой дом труба шатал

Труба у тебя еще не отросла. Так что такое plain file?

tailgunner ★★★★★
()

Тупой теcт while(1) kill(getppid(), SIGHUP); в ребенке очень быстро дает EINTR на splice() в родителе.

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

да, именно. что-то меня переклинило, но я имел в виду regular file.

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

Это, конечно, ясно. но может ли сплайс сплайснуть часть данных если пришёл сигнал? или же он атомарно сплайсит максимально большой объем данных ?

Конечно, можно прочитать исходники и понять как это работает сейчас. но вопрос - как оно должно работать по задумке авторов? а то вдруг то что сейчас - это баг, а может, фича, а может unpredictable result. не понятно же.

Короче. Меня интересует, возможно ли вообще надёжное использование техники, описанной в A9 без блокировки сигналов?

По ходу — нет. Видимо придется использвать epoll_pwait либо signalfd и блокировать сигналы нафиг....

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

Обычно приход сигнала - событие достаточно редкое по сравнению с основной массой событий, поэтому от того, что вы дёрните лишний раз epoll, никакого замедления производительности не будет.

Более того, можно даже не использовать epoll напрямую, а полагаться на готовые отлаженные библиотеки работы с событиями, существенно упрощающие жизнь и позволяющие экономить время разработки. Libevent, например, - очень неплохая библиотека. С версии 2.0 в ней появилась и поддержка sendfile.

А вообще, мне показалось или нет, что Вы от write на обычном файле рассчитываете в каком-то случае получить EWOULDBLOCK?

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