There are definitely bugs and system-dependent behaviour* in these areas.  Just a couple years ago I ran into one that lead to me writing a "handle_expt()" method with this comment before it: 

    #   Semi-crazy method that is working around a sort-of bug within 
    #   asyncore.  When using select-based I/O multiplexing, the POLLHUP 
    #   the socket state is indicated by the socket becoming readable, 
    #   and not by indicating an exceptional event.
    #   When using POLL instead, the flag returned indicates precisely 
    #   what the state is because "flags & select.POLLHUP" will be true.
    #   In the former case, when using select-based I/O multiplexing, 
    #   select's indication that the the descriptor has become readable 
    #   leads to the channel's handle read event method being invoked.  
    #   Invoking receive on the socket then returns an empty string, 
    #   which is taken by the channel as an indication that the socket 
    #   is no longer connected and the channel correctly shuts itself 
    #   down.
    #   However, asyncore's current implementation of the poll-based 
    #   I/O multiplex event handling invokes the channel's 
    #   handle exceptional data event anytime "flags & POLLHUP" is true.  
    #   While select-based multiplexing would only call this method when 
    #   OOB or urgent data was detected, it can now be called for POLLHUP 
    #   events too.
    #   Under most scenarios this is not problematic because poll-based 
    #   multiplexing also indicates the descriptor is readable and 
    #   so the handle read event is also called and therefore the 
    #   channel is properly close, with only an extraneous invocation 
    #   to handle exceptional event being a side-effect.  Under certain 
    #   situations, however, the socket is not indicated as being 
    #   readable, only that it has had an exceptional data event.  I 
    #   believe this occurs when the attemtp to connect never succeeds, 
    #   but a POLLHUP does.  Previously this lead to a busy loop, which 
    #   is what this method fixes.

Shane Green
805-452-9666 |

On Oct 14, 2012, at 4:55 PM, Richard Oudkerk <> wrote:

On 14/10/2012 11:45pm, Greg Ewing wrote:
It does indeed contradict me. It looks like this is
implementation-dependent, because I distinctly remember
encountering a bug once that I traced back to the fact
that I wasn't servicing *all* the fds reported as ready
before making another select call.

Could it have been that some fds were being starved because the earlier ones in the lists were getting priority?  Servicing all fds reported prevents such starvation problems.


Python-ideas mailing list