Почему epoll_wait() не реагирует на dup2(writable_fd, non_writable_fd)?
Давайте представим, что я добавил не доступный для записи fd в epoll watcher, чтобы ждать, когда он станет доступным для записи.
epoll_ctl(epollfd, EPOLL_CTL_ADD, non_writable_fd, {EPOLLOUT})
non_writable_fd
все еще не для записи и epoll_wait
вернет 0 готовых фдс
Тогда я сделаю это
dup2(writable_fd, non_writable_fd)
куда writable_fd
дескриптор файла, который доступен для записи Теперь я ожидаю, что epoll_wait
вернет 1 FD немедленно. Но, к сожалению, все равно тайм-ауты с 0 fd вернулись.
Почему эта техника не работает с epoll
когда это работает с select
а также poll
?
1 ответ
Проблема в том, что epoll
заботится о "открытых описаниях файлов", а не о дескрипторах файлов. Ответ скрыт в нескольких слоях справочных страниц. Первый, epoll_wait
:
Будет ли закрытие файлового дескриптора причиной его автоматического удаления из всех наборов epoll?
Да, но учтите следующий момент. Описатель файла - это ссылка на описание открытого файла (см. Open(2))[...]
Вернуться к вашему dup2
вызов:
dup2(writable_fd, non_writable_fd)
dup2
вызов атомарно сначала закрывается non_writable_fd
а затем указывает на то же описание файла, что и writable_fd
, Рассмотрим 2 случая:
Вы не сделали ничего особенного, так что ваш
dup2
заканчивается закрытием описания открытого файла, связанного сnon_writable_fd
, В этом случаеepoll
просто удаляет его из набора и это всеВы имели заранее
dup
d"non_writable_fd
во что-то еще. В этом случаеdup2
просто разрывает связь междуnon_writable_fd
и его OFD, который живет, смотритepoll
В обеих ситуациях ваш dup
вызов не достигает того, что вы хотите: вам нужно явно позвонить epoll_ctl
снова.