> > >>>Also, for the record we usually get a bunch of these quite often: >>> >>>2001-11-04T09:04:33 ERROR(200) ZServer uncaptured >>> python exception, closing channel <zhttp_channel connected >>> XXX.XXX.XXX.XXX:2181 at fb4edc channel#: 2286 requests:4> >>> (socket.error:(32, 'Broken pipe') >>> >>>[/usr/local/zope/dist/Zope-2.4.1/ZServer/medusa/asynchat.py|initiate_send|21 >>>4] [/usr/local/zope/dist/Zope-2.4.1/ZServer/medusa/http_server.py|send|414] >>>[/usr/local/zope/sw/Python2.1.1/lib/python2.1/asyncore.py|send|330]) >>> >>> >>>We were seeing the same error (asyncore.py|send|330, etc) on solaris. >>> >>> > >
For what its worth, I tracked this down in the sources and confirmed that in Zope 2.3, we shipped a modified asyncore.py with Medusa that handled EINTR, but in Zope 2.4 we used stock Python's asyncore which does NOT handle EINTR being returned from select(). IMHO, the distributed Python 2.1 asyncore behavior is incorrect. I've attached a diff of a portion of the differences (manually edited to take out other patches). I suspect this patch never got integrated due to ugliness of "while 1" Also, the "what should this be" comment relates to NT's error numbers. Visual C++ has an errno.h that lists EINTR as 4 -- And winsock.h defines WSAEINTR as 10004 (ie add 10,000 to the errno). SO that number should be 10004, not 0 for correctness on Windows.
--- /usr/local/python-2.1.1/lib/python2.1/asyncore.py Fri Nov 9 16:28:15 2001 +++ asyncore.py Sun Oct 1 11:58:56 2000 @@ -59,8 +39,10 @@ ECONNRESET = 10054 ENOTCONN = 10057 ESHUTDOWN = 10058 + EINTR = 0 # what should this be? else: - from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN + from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET + from errno import ENOTCONN, ESHUTDOWN, EINTR try: socket_map @@ -83,7 +65,13 @@ r.append (fd) if obj.writable(): w.append (fd) - r,w,e = select.select (r,w,e, timeout) + + while 1: + try: r,w,e = select.select (r,w,e, timeout) + except select.error, v: + if v[0] != EINTR: raise + else: break + if DEBUG: print r,w,e