Почему 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 случая:

  1. Вы не сделали ничего особенного, так что ваш dup2 заканчивается закрытием описания открытого файла, связанного с non_writable_fd, В этом случае epoll просто удаляет его из набора и это все

  2. Вы имели заранее dupd" non_writable_fd во что-то еще. В этом случае dup2 просто разрывает связь между non_writable_fd и его OFD, который живет, смотрит epoll

В обеих ситуациях ваш dup вызов не достигает того, что вы хотите: вам нужно явно позвонить epoll_ctl снова.

Другие вопросы по тегам