Для чего именно kqueue EV_RECEIPT?

Механизм kqueue имеет флаг события EV_RECEIPT, который, согласно связанной справочной странице:

... полезен для внесения массовых изменений в очередь без сброса ожидающих событий. При передаче в качестве входных данных он всегда возвращает EV_ERROR. При успешном добавлении фильтра поле данных будет равно нулю.

Насколько я понимаю, однако, тривиально вносить массовые изменения в kqueue, не удаляя какие-либо ожидающие события, просто передавая 0 для параметра nevents в kevent и, таким образом, не вытягивая события из очереди. Имея это в виду, почему EV_RECEIPT необходимо?

Некоторый пример кода в документации Apple для OS X фактически использует EV_RECEIPT:

kq = kqueue();

EV_SET(&changes, gTargetPID, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL);
(void) kevent(kq, &changes, 1, &changes, 1, NULL);

Но, поскольку массив changes никогда не проверяется после вызова kevent, мне совершенно непонятно, почему в данном случае использовалось EV_RECEIPT.

Действительно ли необходим EV_RECEIPT? В какой ситуации это было бы действительно полезно?


person davmac    schedule 09.06.2016    source источник


Ответы (1)


Если вы вносите массовые изменения, и одно из них вызывает ошибку, то событие будет помещено в eventlist с установкой EV_ERROR в flags и системной ошибкой в ​​data.

Следовательно, можно определить, какой элемент changelist вызвал ошибку.

Если вы установите nevents равным нулю, вы получите код ошибки, но не укажете, какое событие вызвало ошибку.

Таким образом, EV_RECEIPT позволяет вам установить nevents в ненулевое значение без слива ожидающих событий.

person Richard Smith    schedule 09.06.2016
comment
Хорошо, это имеет смысл, но это не коррелирует с кодом в примере Apple, на который я ссылался. Комментарий к этому коду гласит: Создайте kqueue и настройте его для отслеживания SIGCHLD. Используйте новый в 10.5 флаг EV_RECEIPT, чтобы убедиться, что мы получаем то, что ожидаем, однако он вызывает kevent только с одним событием, использует EV_RECEIPT и не проверяет ни возврат из kevent, ни значения в возвращаемых событиях. . Любая подсказка относительно того, что означает комментарий, когда мы получаем то, что ожидаем? - или использование EV_RECEIPT в этом случае является подделкой? - person davmac; 10.06.2016
comment
Я думаю, что в этом случае установка nevents на ноль приведет к идентичному поведению, поскольку возвращаемое значение не проверяется. Но это может быть шаблон, который воспроизводится в другом коде, где проверяется возвращаемое значение проверяется. Ожидается, что будет возвращен новый фильтр, а не ожидающее событие. - person Richard Smith; 10.06.2016