diff --git a/Lib/asyncore.py b/Lib/asyncore.py --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -102,15 +102,17 @@ except: obj.handle_error() -def readwrite(obj, flags): +def readwrite(obj, flags, map=None): + # 'map' may be None for backward compatibility try: - if flags & select.POLLIN: + if (not map or obj._fileno in map) and flags & select.POLLIN: obj.handle_read_event() - if flags & select.POLLOUT: + if (not map or obj._fileno in map) and flags & select.POLLOUT: obj.handle_write_event() - if flags & select.POLLPRI: + if (not map or obj._fileno in map) and flags & select.POLLPRI: obj.handle_expt_event() - if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): + if ((not map or obj._fileno in map) and + flags & (select.POLLHUP|select.POLLERR|select.POLLNVAL)): obj.handle_close() except socket.error as e: if e.args[0] not in _DISCONNECTED: @@ -190,7 +192,7 @@ obj = map.get(fd) if obj is None: continue - readwrite(obj, flags) + readwrite(obj, flags, map) poll3 = poll2 # Alias for backward compatibility diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -610,17 +610,25 @@ def test_handle_close(self): # make sure handle_close is called when the other end closes - # the connection + # the connection, and that it is closed only once class TestClient(BaseClient): + def __init__(self, family, address): + BaseClient.__init__(self, family, address) + self.count = 0 + def handle_read(self): # in order to make handle_close be called we are supposed # to make at least one recv() call self.recv(1024) def handle_close(self): - self.flag = True + self.count += 1 + if self.count == 1: + self.flag = True + else: + self.flag = False self.close() class TestHandler(BaseTestHandler):