diff options
author | Ali-Akber Saifee <ali@indydevs.org> | 2023-04-13 04:46:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-13 04:46:52 (GMT) |
commit | 19d2639d1e6478e2e251479d842bdfa2e8272396 (patch) | |
tree | 56b20f455cc63ee8180cc10141c36aff67c732b5 /Lib | |
parent | 9e677406ee6666b32d869ce68c826519ff877445 (diff) | |
download | cpython-19d2639d1e6478e2e251479d842bdfa2e8272396.zip cpython-19d2639d1e6478e2e251479d842bdfa2e8272396.tar.gz cpython-19d2639d1e6478e2e251479d842bdfa2e8272396.tar.bz2 |
gh-103462: Ensure SelectorSocketTransport.writelines registers a writer when data is still pending (#103463)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/asyncio/selector_events.py | 3 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_selector_events.py | 42 |
2 files changed, 45 insertions, 0 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index de5076a..3a69712 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -1176,6 +1176,9 @@ class _SelectorSocketTransport(_SelectorTransport): return self._buffer.extend([memoryview(data) for data in list_of_data]) self._write_ready() + # If the entire buffer couldn't be written, register a write handler + if self._buffer: + self._loop._add_writer(self._sock_fd, self._write_ready) def can_write_eof(self): return True diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 921c98a..e41341f 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -748,6 +748,48 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.assertEqual(list_to_buffer([b'data']), transport._buffer) @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_writelines_sendmsg_full(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = len(data) + + transport = self.socket_transport(sendmsg=True) + transport.writelines([data]) + self.assertTrue(self.sock.sendmsg.called) + self.assertFalse(self.loop.writers) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_writelines_sendmsg_partial(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = 2 + + transport = self.socket_transport(sendmsg=True) + transport.writelines([data]) + self.assertTrue(self.sock.sendmsg.called) + self.assertTrue(self.loop.writers) + + def test_writelines_send_full(self): + data = memoryview(b'data') + self.sock.send.return_value = len(data) + self.sock.send.fileno.return_value = 7 + + transport = self.socket_transport() + transport.writelines([data]) + self.assertTrue(self.sock.send.called) + self.assertFalse(self.loop.writers) + + def test_writelines_send_partial(self): + data = memoryview(b'data') + self.sock.send.return_value = 2 + self.sock.send.fileno.return_value = 7 + + transport = self.socket_transport() + transport.writelines([data]) + self.assertTrue(self.sock.send.called) + self.assertTrue(self.loop.writers) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') def test_write_sendmsg_full(self): data = memoryview(b'data') self.sock.sendmsg = mock.Mock() |