diff options
-rw-r--r-- | Lib/asyncio/selector_events.py | 64 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_selector_events.py | 36 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst | 1 |
3 files changed, 48 insertions, 53 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index f895750..d521b4e 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -274,9 +274,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _add_reader(self, fd, callback, *args): self._check_closed() handle = events.Handle(callback, args, self, None) - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: self._selector.register(fd, selectors.EVENT_READ, (handle, None)) else: @@ -290,30 +289,27 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _remove_reader(self, fd): if self.is_closed(): return False - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: return False + mask, (reader, writer) = key.events, key.data + mask &= ~selectors.EVENT_READ + if not mask: + self._selector.unregister(fd) else: - mask, (reader, writer) = key.events, key.data - mask &= ~selectors.EVENT_READ - if not mask: - self._selector.unregister(fd) - else: - self._selector.modify(fd, mask, (None, writer)) + self._selector.modify(fd, mask, (None, writer)) - if reader is not None: - reader.cancel() - return True - else: - return False + if reader is not None: + reader.cancel() + return True + else: + return False def _add_writer(self, fd, callback, *args): self._check_closed() handle = events.Handle(callback, args, self, None) - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: self._selector.register(fd, selectors.EVENT_WRITE, (None, handle)) else: @@ -328,24 +324,22 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): """Remove a writer callback.""" if self.is_closed(): return False - try: - key = self._selector.get_key(fd) - except KeyError: + key = self._selector.get_map().get(fd) + if key is None: return False + mask, (reader, writer) = key.events, key.data + # Remove both writer and connector. + mask &= ~selectors.EVENT_WRITE + if not mask: + self._selector.unregister(fd) else: - mask, (reader, writer) = key.events, key.data - # Remove both writer and connector. - mask &= ~selectors.EVENT_WRITE - if not mask: - self._selector.unregister(fd) - else: - self._selector.modify(fd, mask, (reader, None)) + self._selector.modify(fd, mask, (reader, None)) - if writer is not None: - writer.cancel() - return True - else: - return False + if writer is not None: + writer.cancel() + return True + else: + return False def add_reader(self, fd, callback, *args): """Add a reader callback.""" diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 47693ea..c22b780 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -178,7 +178,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): sock.connect.assert_called_with(('127.0.0.1', 0)) def test_add_reader(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} cb = lambda: True self.loop.add_reader(1, cb) @@ -192,8 +192,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_add_reader_existing(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (reader, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (reader, writer))} cb = lambda: True self.loop.add_reader(1, cb) @@ -208,8 +208,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_add_reader_existing_writer(self): writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (None, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (None, writer))} cb = lambda: True self.loop.add_reader(1, cb) @@ -222,8 +222,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): self.assertEqual(writer, w) def test_remove_reader(self): - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_READ, (None, None)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_READ, (None, None))} self.assertFalse(self.loop.remove_reader(1)) self.assertTrue(self.loop._selector.unregister.called) @@ -231,9 +231,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_remove_reader_read_write(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, - (reader, writer)) + (reader, writer))} self.assertTrue( self.loop.remove_reader(1)) @@ -243,12 +243,12 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): self.loop._selector.modify.call_args[0]) def test_remove_reader_unknown(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} self.assertFalse( self.loop.remove_reader(1)) def test_add_writer(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} cb = lambda: True self.loop.add_writer(1, cb) @@ -262,8 +262,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_add_writer_existing(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_READ, (reader, writer)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_READ, (reader, writer))} cb = lambda: True self.loop.add_writer(1, cb) @@ -277,8 +277,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): self.assertEqual(cb, w._callback) def test_remove_writer(self): - self.loop._selector.get_key.return_value = selectors.SelectorKey( - 1, 1, selectors.EVENT_WRITE, (None, None)) + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( + 1, 1, selectors.EVENT_WRITE, (None, None))} self.assertFalse(self.loop.remove_writer(1)) self.assertTrue(self.loop._selector.unregister.called) @@ -286,9 +286,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_remove_writer_read_write(self): reader = mock.Mock() writer = mock.Mock() - self.loop._selector.get_key.return_value = selectors.SelectorKey( + self.loop._selector.get_map.return_value = {1: selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, - (reader, writer)) + (reader, writer))} self.assertTrue( self.loop.remove_writer(1)) @@ -298,7 +298,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): self.loop._selector.modify.call_args[0]) def test_remove_writer_unknown(self): - self.loop._selector.get_key.side_effect = KeyError + self.loop._selector.get_map.return_value = {} self.assertFalse( self.loop.remove_writer(1)) diff --git a/Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst b/Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst new file mode 100644 index 0000000..204bda1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst @@ -0,0 +1 @@ +Reduce overhead to add and remove :mod:`asyncio` readers and writers. |