Я работаю с многопоточным встроенным приложением, в котором epoll используется для ввода-вывода в одном из потоков. Я полагаюсь на особую функцию epoll, которая указывает, что закрытие файлового дескриптора автоматически удаляет его из набора epoll (Вопрос / Ответ 6 в man 7 epoll). В этом случае закрытие дескриптора файла выполняется в том же потоке, что и epoll_wait
вызывается. Что в итоге происходит, так это epoll_wait
возвращает событие в файловом дескрипторе после того, как оно было закрыто, и программа завершается сбоем, потому что она пытается получить доступ к ресурсам, которые были освобождены, когда файловый дескриптор был закрыт. Насколько я знаю, файловый дескриптор нигде не дублируется, хотя я не знаю, как это проверить. Я точно знаю, что нет звонков fork()
, dup()
, dup2()
, или же fcntl()
с конкретной опцией dup. Этот конкретный файловый дескриптор зарегистрирован EPOLLOUT
, EPOLLIN
, EPOLLERR
, а также EPOLLHUP
, Он запускается на уровне. Есть ли какие-либо оговорки к этой функции, о которых кто-нибудь знает? Справочная страница неверна? Любая полезная информация, которая может помочь мне в дальнейшей отладке проблемы? Я знаю, что могу просто удалить дескриптор файла из набора, но я хотел бы знать, почему это происходит.
Закрытие дескриптора файла, похоже, не удаляет его из epoll. Я попробовал это с очень простым примером на 3.12.2. Я склонен называть справочную страницу неправильной или неточной.
Что я сделал в тесте было:
Ожидание работает, даже если розетка была закрыта, независимо от того, подключен я к ней или нет.
Редактировать: The epoll_ctl_del
не удалось, если сокет был закрыт. И после прочтения текущих страниц руководства кажется, что они на самом деле в порядке. Страница epoll указывает select (2) о закрытии отслеживаемого сокета, и эта страница говорит, что поведение не определено.
Других решений пока нет …