- Реактор вызывает
MsgWaitForMultipleObjects
с некоторым сокетом ручки иQS_ALLINPUT
. - Вызов завершается и указывает, что дескриптор сокета в этом состоянии (т. е. имеет байты, ожидающие чтения и закрытые узлом) активен.
- Реактор отправляет это уведомление общая реализация TCP.
- Реализация TCP считывает доступные байты из сокета. Есть некоторые, они доставляются в код приложения.
- Управление возвращается к реактору, который в конце концов снова вызывает
MsgWaitForMultipleObjects
. MsgWaitForMultipleObjects
больше никогда не указывает, что дескриптор активен. Реализация TCP больше никогда не просматривает сокет, поэтому она никогда не сможет обнаружить, что соединение закрыто.
Это создает впечатление, что MsgWaitForMultipleObjects
— это механизм уведомления, запускаемый фронтом. документация MSDN говорит:
Waits until one or all of the specified objects are in the signaled state
or the time-out interval elapses.
Это не похоже на краевое срабатывание. Это похоже на срабатывание уровня.
Действительно ли MsgWaitForMultipleObjects
срабатывает по фронту? Или это вызвано уровнем, и это неправильное поведение вызвано каким-то другим аспектом его поведения?
Дополнение Документы MSDN для WSAEventSelect немного подробнее объясняют, что здесь происходит, включая указание на то, что FD_CLOSE
в основном является разовым событием. После того, как он сигнализируется один раз, вы никогда не получите его снова. Это в какой-то мере объясняет, почему у Twisted такая проблема. Однако мне все еще интересно узнать, как эффективно использовать MsgWaitForMultipleObjects
с учетом этого ограничения.