ionotify()

Подготовить менеджер ресурсов к отправке уведомления

Прототип:

#include <unistd.h>
#include <sys/iomsg.h>
int ionotify( int fd,
int action,
int flags,
const struct sigevent *event );

Аргументы:

fd
Файловый дескриптор, связанный с менеджером ресурсов, который требуется уведомить.
action
Тип действий для уведомления. См. “Действия” ниже.
flags
Типы условий, которые требуется проверить для уведомления. См. “Флаги” ниже.
event
Указатель на struct sigevent, определяющую событие, которое менеджер ресурсов отправит в качестве уведомления или NULL для отключения уведомления.

Библиотека:

libc

Описание:

Функция notify() взводит менеджер ресурсов, связанный с fd, для отправки уведомления о событии event. Событие отправляется, когда возникает условие, указанное комбинацией action и flags.

Флаги

Аргумент flags указывает типы условий, которые требуется проверять для уведомления. Каждый менеджер ресурсов поддерживает отдельный контекст для каждого условия уведомления. Затрагиваются только указанные биты уведомлений. В следующем примере второй вызов inotify() не влияет на первый, поскольку он указывает другое уведомление:

ionotify( fd, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT, &event );
ionotify( fd, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_OUTPUT, &event );

Условия, указанные в flags:

_NOTIFY_COND_OBAND
Доступны нештатные данные. Определение нештатных данных зависит от менеджера ресурсов.
_NOTIFY_COND_OUTPUT
В выходном буфере есть место для дополнительных данных. Количество свободного места, необходимого для выполнения этого условия, зависит от менеджера ресурсов. Некоторые менеджеры ресурсов могут по умолчанию подразумевать пустой выходной буфер, в то время как другие, что свободна только какая-то часть буфера.
_NOTIFY_COND_INPUT
Доступны входные данные. Объем доступных данных по умолчанию равен 1. Для символьного устройства, такого как последовательный порт, это будет символ. Для очереди сообщений POSIX это будет сообщение. Каждый менеджер ресурсов выбирает соответствующий объект.
_NOTIFY_COND_EXTEN
Условия определяются следующими расширенными флагами:
_NOTIFY_CONDE_RDNORM
доступны обычные данные; то же самое, что и _NOTIFY_COND_INPUT.
_NOTIFY_CONDE_WRNORM
есть место для обычных данных; то то же самое, что и _NOTIFY_COND_OUTPUT.
_NOTIFY_CONDE_RDBAND
доступны нештатные данные; то то же самое, что и _NOTIFY_COND_OBAND.
_NOTIFY_CONDE_PRI
доступны приоритетные данные.
_NOTIFY_CONDE_WRBAND
есть место для OOB данных.
_NOTIFY_CONDE_ERR
произошла ошибка устройства или потока.
_NOTIFY_CONDE_HUP
устройство было отключено.
_NOTIFY_CONDE_NVAL
недопустимый дескриптор файла.

Способ изменения значения по умолчанию для _NOTIFY_COND_OUTPUT и _NOTIFY_COND_INPUT зависит от устройства. Например, специальные символьные устройства могут вызывать readcond().

Для менеджеров ресурсов, поддерживающих как редактируемый, так и сырой режим, должен быть установлен сырой режим, чтобы обеспечить правильную работу ionotify().

Вышеуказанные флаги расположены в старших битах flags. Они определяются маской _NOTIFY_COND_MASK.

В случае асинхронного уведомления с использованием переданного event, такого как пульс или сигнал реального времени, 32-битное значение в event->sigev_value.sival_int возвращается неизменённым, если не выбран код SI_NOTIFY, в этом случае старшие биты (определённые _NOTIFY_COND_MASK) устанавливаются для активных уведомлений. В этом случае следует ограничить sival_int маской, определённой _NOTIFY_DATA_MASK.

Например, функция Unix select() определяет SI_NOTIFY и использует допустимые биты данных sival_int в качестве серийного номера.


Note: Если используется код SI_NOTIFY, то следует очистить биты в поле sigev_value в соответствии с _NOTIFY_COND_MASK — менеджер ресурсов использует только операцию ИЛИ и никогда не очищает биты.

Действия

Аргумент action указывает тип взводимого действия, которое необходимо выполнить. Когда условие включено, менеджер ресурсов отслеживает его и при выполнении доставляет event с помощью MsgDeliverEvent(). Когда событие доставлено, оно всегда отключается, за исключением случаев, указанных ниже.

Обратите внимание, что для взвода события (указанного в action) _NOTIFY_ACTION_TRANARM на устройство может быть выдано только одно уведомление такого типа. Когда событие срабатывает, оно удаляется.

Каждое действие предназначено для поддержки определенного типа уведомлений следующим образом:

_NOTIFY_ACTION_POLL
Это действие выполняет опрос условий уведомления, указанных в flags. Не взводит событие и отменяет все другие асинхронные уведомления о событиях, установленных предыдущим вызовом ionotify(), что позволяет использовать его в качестве простого сброса. Возвращает активные условия в соответствии с запрошенными flags.
_NOTIFY_ACTION_POLLARM
Это действие выполняет опрос таким же образом, как и _NOTIFY_ACTION_POLL. Однако, если ни одно из условий, указанных во flags, не выполнено, то каждое условие, указанное в flags, активируется. Если какое-либо условие выполнено, ни одно из условий не взводится. Функция Unix select() использует notify() с этим действием. Возвращает активные условия в соответствии с запрошенными flags.
_NOTIFY_ACTION_TRANARM
Это действие взводится для переходов условий уведомлений, указанных в flags. Переход определяется как переход данных из пустого состояния в непустое при вводе. Использование на вывод не определено. Обратите внимание, что если при использовании этого вызова будут доступны данные, переход не произойдет. Чтобы сгенерировать событие с использованием этого типа уведомления, необходимо включить событие, а затем опустошить входные данные с помощью неблокирующего чтения. После этого новые входные данные приведут к доставке события. Функция mq_notify() использует ionotify() с этим действием. Поскольку активируется для перехода, возвращаемое значение всегда равно нулю.

Можно использовать действия _NOTIFY_ACTION_POLLARM или _NOTIFY_ACTION_POLL для генерации событий, ориентированных на уровень срабатывания, а не на переход.

Когда действие в менеджере ресурсов активировано, оно остается включенным до тех пор пока:


Note: Существует ограничение в одно уведомление на очередь сообщений или менеджер ресурсов. Если уведомление уже было включено для указанного ресурса, notify() устанавливает ошибку EBUSY.

Возвращаемое значение:

Активные условия в соответствии с запрошенными flags. Для действия с переходом возвращает 0. Если возникла ошибка возвращает -1, код ошибки записывается в errno.

Коды ошибок:

EBADF
Соединение fd не существует или fd больше не подключен к каналу.
EBUSY
Уведомление для этого ресурса уже активировано; эта функция накладывает ограничение в одно уведомление на очередь сообщений или менеджер ресурсов.
EFAULT
Ошибка при попытке ядра обратиться к предоставленным буферам. Могло произойти при приёме или ответе.
EINTR
Вызов был прерван сигналом.
ENOMEM
Менеджеру ресурсов не удалось выделить память для уведомления, чтобы сохранить запрос.
ENOSYS
Запрошенное действие не поддерживается менеджером ресурсов.
ESRVRFAULT
Произошёл сбой в адресном пространстве сервера при доступе к буферам сообщений сервера. Это могло произойти при приёме или ответе.
ETIMEDOUT
Тайм-аут ядра разблокировал вызов. См. TimerTimeout().

Классификация:

ЗОСРВ «Нейтрино»

Безопасность использования
Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

mq_notify(), select(), struct sigevent




Предыдущий раздел: Описание API системной библиотеки