Problem: If the loop() function of asyncore is invoked with poll rather than select, the function readwrite() is used when I/O is available on a socket. However, this function does not check for hangup - provided by POLLHUP. If a socket is attempting to write, then POLLOUT never gets set, so the socket hangs. Because poll() is returning immediately, but the return value is never used, asyncore busy-loops, consuming all available CPU. Possible solutions: The easy solution is to check for POLLHUP in the readwrite() function: if flags & (select.POLLOUT | select.POLLHUP): obj.handle_write_event() This makes the poll work exactly like the select - the application raises a socket.error set to EPIPE. An alternate solution - possibly more graceful - is to invoke the handle_close() method of the object: if flags & select.POLLHUP: obj.handle_close() else: if flags & select.POLLIN: obj.handle_read_event() if flags & select.pollout: obj.handle_write_event() This is incompatible with the select model, but it means that the read and write logic is now the same for socket hangups - handle_close() is invoked.
Logged In: YES user_id=410460 Perhaps, it would be better to raise exception: def readwrite(obj, flags): try: if flags & (select.POLLIN | select.POLLPRI): obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() if flags & (select.POLLERR
select.POLLHUP
select.POLLNVAL): obj.handle_expt_event() except ExitNow: raise except: obj.handle_error() ... def handle_expt_event(self): err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) assert(err != 0) raise socket.error, (err, errorcode[err]) Since asyncore closes socket in handle_error, this solves the problem too.
The solution suggested by klimkin seems to have made it into revision 35513 as a fix to bug #887279. I'm not sure that this is necessarily the right solution to this bug or #887279, as a socket disconnect isn't necessarily an error condition, otherwise .handle_close_event() shouldn't exist for select-based loops, and it should always be an error. Suggest switching to the last if clause of readwrite() to... if flags & (select.POLLERR | select.POLLNVAL): obj.handle_expt_event() if flags & select.POLLHUP: obj.handle_close_event()