epoll_pwait - ждать события ввода/вывода на файловом дескрипторе
epoll_pwait(2)
ждать события ввода/вывода на файловом дескрипторе
Other Alias
epoll_wait
ОБЗОР
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);
ОПИСАНИЕ
Системный вызов
epoll_wait() ожидает события на экземпляре
epoll(7),
на который указывает файловый дескриптор
epfd. Область памяти, на которую
указывает
events, будет содержать события, доступные для
вызываемого. Вызов
epoll_wait() может вернуть до
maxevents
событий. Параметр
maxevents должен быть больше нуля.
В аргументе timeout указывается количество миллисекунд, на которые
блокируется epoll_wait(). Вызов будет заблокирован пока:
событие не будет доставлено в файловый дескриптор;
вызов не прервётся обработчиком сигнала;
не истечёт время ожидания.
Заметим, что интервал timeout будет округлён в соответствии с точностью
системных часов, а задержки ядерного планирования приведут к тому, что
интервал блокировки может быть немного больше. Если присвоить timeout
значение -1, то epoll_wait() блокируется навсегда; если значение
timeout равно 0, то epoll_wait() сразу завершает работу, даже если
никаких событий не произошло.
Структура struct epoll_event определена так:
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* События epoll */
epoll_data_t data; /* Переменная для данных пользователя */
};
Поле data в каждой возвращаемой структуре будет содержать данные
пользователя, установленные с помощью epoll_ctl(2) (EPOLL_CTL_ADD,
EPOLL_CTL_MOD), а в поле events будет содержаться битовое поле
возвращаемого события.
epoll_pwait()
Отношения между epoll_wait() и epoll_pwait() аналогичны родству
select(2) и pselect(2): как pselect(2), epoll_pwait() позволяет
приложению безопасно ждать, пока файловый дескриптор не станет готов или
пока не будет получен сигнал.
Вызов epoll_pwait():
ready = epoll_pwait(epfd, &events, maxevents, timeout, &sigmask);
эквивалентен атомарному выполнению следующих вызовов:
sigset_t origmask;
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = epoll_wait(epfd, &events, maxevents, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
Аргумент sigmask может быть равен NULL --- в этом случае
epoll_pwait() эквивалентен epoll_wait().
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При нормальном выполнении epoll_wait() возвращает количество файловых
дескрипторов, готовых для запросов ввода-вывода, или ноль, если ни один
файловый дескриптор не стал готов за отведённые timeout миллисекунд. При
возникновении ошибки epoll_wait() возвращает -1 и устанавливает errno
в соответствующее значение.
ОШИБКИ
EBADF
Значение epfd не является правильным файловым дескриптором.
EFAULT
Память, указанная events, недоступна на запись из-за прав доступа.
EINTR
Вызов был прерван обработчиком сигнала до возникновения любого из
запрошенных событий или истечения timeout; см. signal(7).
EINVAL
epfd не является файловым дескриптором epoll, или maxevents меньше
или равно нулю.
ВЕРСИИ
Вызов epoll_wait() был добавлен в ядро версии 2.6. В glibc
соответствующая функция появилась в версии 2.3.2.
Вызов epoll_pwait() был добавлен в ядро Linux 2.6.19. В glibc
соответствующая функция появилась в версии 2.6.
СООТВЕТСТВИЕ СТАНДАРТАМ
Вызов epoll_wait() есть только в Linux.
ЗАМЕЧАНИЯ
Пока одна нить блокирована в вызове epoll_pwait(), в другой нити возможно
добавить файловый дескриптор, который будет ожидаться экземпляром
epoll. Как только новый файловый дескриптор станет готовым, это
разблокирует вызов epoll_wait().
Обсуждение того, что может случиться, если файловый дескриптор в экземпляре
epoll отслеживается epoll_wait() и при этом закрывается в другой нити,
смотрите в select(2).
ДЕФЕКТЫ
В ядрах до версии 2.6.37, если значение timeout больше чем
приблизительное LONG_MAX / HZ секунд, то оно воспринимается как -1 (т.е.,
бесконечность). То есть, например, в системе, где sizeof(long) равно 4 и
значение ядра HZ равно 1000, задержка более 35,79 минут считается
бесконечностью.
Отличия между библиотекой C и ядром
Ядерный системный вызов epoll_pwait() имеет шестой аргумент, size_t
sigsetsize, в котором указывается размер аргумента sigmask в байтах. В
обёрточной функции glibc epoll_pwait() в этом аргументе передаётся
постоянная величина (равная sizeof(sigset_t)).