Главная » 2017 » Ноябрь » 21 » man 2 ppoll
01:19
man 2 ppoll

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


poll, ppoll - ожидает некоторое событие над файловым дескриптором



ОБЗОР


#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

#define _GNU_SOURCE /* смотрите feature_test_macros(7) */
#include <signal.h>
#include <poll.h>

int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *tmo_p, const sigset_t *sigmask);



ОПИСАНИЕ


Вызов poll() выполняет сходную с select(2) задачу: он ждёт пока один дескриптор из
набора файловых дескрипторов не станет готов выполнить операцию ввода-вывода.

Отслеживаемый набор файловых дескрипторов задаётся в аргументе fds, который
представляет собой массив структур:

struct pollfd {
int fd; /* файловый дескриптор */
short events; /* запрашиваемые события */
short revents; /* возвращённые события */
};

Вызывающий должен указать количество элементов в массиве fds в аргументе nfds.

В поле fd содержится файловый дескриптор открытого файла. Если значение поля
отрицательно, то соответствующее поле events игнорируется, а полю revents
возвращает ноль (простой способ игнорирования файлового дескриптора в одиночном
вызове poll(): просто сделать значение поля fd отрицательным. Заметим, что это
нельзя использовать для игнорирования файлового дескриптора 0).

Поле events представляет собой входной параметр — битовую маску, указывающую на
события, происходящие с файловым дескриптором fd, которые важны для приложения.
Если это поле равно нулю, то возвращаемыми событиями в revents могут быть POLLHUP,
POLLERR и POLLNVAL (смотрите ниже).

Поле revents представляет собой параметр-результат, в который ядро помещает
информацию о произошедших событиях. В revents могут содержаться любые битовые
флаги из задаваемых в events, или там может быть одно из значений: POLLERR,
POLLHUP или POLLNVAL. Эти три битовых флага не имеют смысла в поле events, но
будут установлены в поле revents, если соответствующее условие истинно.

Если ни одно из запрошенных событий с файловыми дескрипторами не произошло или не
возникло ошибок, то poll() блокируется до их появления.

В аргументе timeout указывается количество миллисекунд, на которые будет
блокироваться poll() в ожидании готовности файлового дескриптора. Вызов будет
заблокирован пока:

* файловый дескриптор не станет готов;

* вызов не прервётся обработчиком сигнала;
Вот возможные биты, описанные в <poll.h>, которые могут быть установлены/получены
в events и revents:

POLLIN Есть данные для чтения.

POLLPRI
Исключительное состояние файлового дескриптора. Может быть из-за:

* Внеполосные данные в сокете TCP (смотрите tcp(7)).

* Мастер псевдо-терминала в пакетном режиме увидел изменение состояния
подчинённого терминала (смотрите ioctl_tty(2)).

* Изменился файл cgroup.events (смотрите cgroups(7)).

POLLOUT
Теперь запись возможна, но запись данных больше, чем доступно места в
сокете или канале, по-прежнему приводит к блокировке (если не указан
O_NONBLOCK).

POLLRDHUP (начиная с Linux 2.6.17)
Удалённая сторона потокового сокета закрыла соединение, или отключила
запись в одну сторону. Для использования данного определения должен быть
определён макрос тестирования свойств _GNU_SOURCE (до включения каких-либо
заголовочных файлов).

POLLERR
Состояние ошибки (возвращается только в revents; игнорируется в events).
Также этот бит устанавливается для файлового дескриптора, указывающего в
пишущий конец канала при закрытом читающем конце.

POLLHUP
Зависание (hang up, возвращается только в revents; игнорируется в events).
Заметим, что при чтении из канала, такого как канал (pipe) или потоковый
сокет, это событие всего-навсего показывает, что партнёр закрыл канал со
своего конца. Дальнейшее чтение из канала будет возвращать 0 (конец файла)
только после потребления всех неполученных данных в канале.

POLLNVAL
Неверный запрос: fd не открыт (возвращается только в revents; игнорируется
в events).

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

POLLRDNORM
Эквивалентно POLLIN.

POLLRDBAND
Доступны для чтения приоритетные внутриполосные данные (в Linux, обычно, не
используется).

POLLWRNORM
Эквивалентно POLLOUT.

POLLWRBAND
Можно писать приоритетные данные.

ready = ppoll(&fds, nfds, tmo_p, &sigmask);

эквивалентен атомарному выполнению следующих вызовов:

sigset_t origmask;
int timeout;

timeout = (tmo_p == NULL) ? -1 :
(tmo_p->tv_sec * 1000 + tmo_p->tv_nsec / 1000000);
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = poll(&fds, nfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);

Смотрите в pselect(2) пояснения о необходимости ppoll().

Если значение аргумента sigmask равно NULL, то изменение маски сигналов не
происходит (и поэтому ppoll() отличается от poll() только в точности аргумента
timeout).

В аргументе tmo_p указывается верхняя граница промежутка времени, на который будет
заблокирован ppoll(). Этот аргумент представляет собой указатель на структуру
следующего вида:

struct timespec {
long tv_sec; /* секунды */
long tv_nsec; /* наносекунды */
};

Если значение tmo_p равно NULL, то ppoll() может оставаться заблокированным
бесконечно.



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ


При успешном выполнении возвращается положительное значение; оно означает
количество структур, в которых поля revents имеют ненулевое значение (другими
словами, тех дескрипторов, для которых возникли события или ошибки). Значение 0
означает, что время ожидания истекло, и нет готовых файловых дескрипторов. В
случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.



ОШИБКИ


EFAULT Указанный аргументом массив содержится вне адресного пространства
вызывающей программы.

EINTR Получен сигнал раньше какого-либо запрашиваемого события; смотрите
signal(7).

EINVAL Значение nfds превышает значение RLIMIT_NOFILE.

ENOMEM Нет места под таблицы файловых дескрипторов.



ВЕРСИИ


Системный вызов poll() появился в Linux 2.1.23. Для старых ядер, в которых этот
вызов отсутствует, glibc (и старая Linux libc) предоставляет обёрточную функцию
poll(), которая эмулируется с помощью select(2).

Системный вызов ppoll() был добавлен в ядро Linux в версии 2.6.16. Библиотечный
вызов ppoll() был добавлен в glibc 2.4.
должны ожидать EAGAIN в цикле, как для EINTR.

В некоторых реализациях определена нестандартная константа INFTIM со значением -1
для использования в качестве значения timeout в poll(). Эта константа отсутствует
в glibc.

Обсуждение того, что может случиться, если файловый дескриптор отслеживается
poll() и при этом закрывается в другой нити, смотрите в select(2).

Отличия между библиотекой C и ядром
В Linux системный вызов ppoll() изменяет свой аргумент tmo_p. Однако, обёрточная
функция glibc скрывает это поведение с помощью локальной переменной для аргумента
timeout, которая передаётся в системный вызов. Поэтому glibc функция ppoll() не
изменяет свой аргумент tmo_p.

Ядерный системный вызов ppoll() имеет пятый аргумент, size_t sigsetsize, в котором
указывается размер аргумента sigmask в байтах. В обёрточной функции glibc ppoll()
в этом аргументе передаётся постоянная величина (равная sizeof(kernel_sigset_t)).
Описание различий sigset между ядерным и библиотечным вызовом смотрите в
sigprocmask(2).



ДЕФЕКТЫ


Смотрите описание ложных уведомлений о готовности в разделе ДЕФЕКТЫ справочной
страницы select(2).



СМОТРИТЕ ТАКЖЕ


restart_syscall(2), select(2), select_tut(2), epoll(7), time(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 379 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar