EINTR ... was Re: [Zope-dev] browser closing connection

Jeremy Hylton jeremy@zope.com
Tue, 11 Dec 2001 09:52:18 -0500 (EST)


>>>>> "MTK" == Matthew T Kromer <matt@zope.com> writes:

  MTK> For what its worth, I tracked this down in the sources and
  MTK> confirmed that in Zope 2.3, we shipped a modified asyncore.py
  MTK> with Medusa that handled EINTR, but in Zope 2.4 we used stock
  MTK> Python's asyncore which does NOT handle EINTR being returned
  MTK> from select().  IMHO, the distributed Python 2.1 asyncore
  MTK> behavior is incorrect.

This is fixed in Python 2.2.

A brief excerpt demonstrates the approach:

def poll (timeout=0.0, map=None):
    if map is None:
        map = socket_map
    if map:
        r = []; w = []; e = []
        for fd, obj in map.items():
            if obj.readable():
                r.append (fd)
            if obj.writable():
                w.append (fd)
        try:
            r,w,e = select.select (r,w,e, timeout)
        except select.error, err:
            if err[0] != EINTR:
                raise

In particular, I didn't use a "while 1:".  I believe an operator could
send a signal to a process using asyncore and expect it to cause the
app to fall out of a poll() call immediately, instead of waiting for
the timeout to occur.  (It might never occur.)

I expect that the interrupted system call will be fairly uncommon, so
it shouldn't matter than the poll() is returning without doing any
work.  In most cases, it will be called from loop() which already has
a while loop.

A similar fix was made in poll3(), which uses the select module's
poll(2) interface.

Jeremy