Twisted includes a reactor implemented on top of MsgWaitForMultipleObjects
. Apparently the reactor has problems reliably noticing when a TCP connection ends, at least in the case where a peer sends some bytes and then quickly closes the connection. What seems to happen is:
MsgWaitForMultipleObjects
with some socket handles and QS_ALLINPUT
.MsgWaitForMultipleObjects
again.MsgWaitForMultipleObjects
never again indicates that the handle is active. The TCP implementation never gets to look at the socket again, so it can never detect that the connection is closed.This makes it appear as though MsgWaitForMultipleObjects
is an edge-triggered notification mechanism. The MSDN documentation says:
Waits until one or all of the specified objects are in the signaled state
or the time-out interval elapses.
This doesn't sound like edge-triggering. It sounds like level-triggering.
Is MsgWaitForMultipleObjects
actually edge-triggered? Or is it level-triggered and this misbehavior is caused by some other aspect of its behavior?
Addendum The MSDN docs for WSAEventSelect explains what's going on here a bit more, including pointing out that FD_CLOSE
is basically a one-off event. After its signaled once, you'll never get it again. This goes some way towards explaining why Twisted has this problem. I'm still interested to hear how to effectively use MsgWaitForMultipleObjects
given this limitation, though.
In order to use WSAEventSelect
and differentiate activities, you need to call WSAEnumNetworkEvents
. Make sure you're processing each event that was reported, not just the first.
WSAAsyncSelect
makes it easy to determine the cause, and is often used together with MsgWaitForMultipleObjects
.
So you might use WSAAsyncSelect
instead of WSAEventSelect
.
Also, I think you have a fundamental misunderstanding of the difference between edge-triggered and level-triggered. Your reasoning seems to be more related to auto-reset vs manual-reset events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With