summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAli-Akber Saifee <ali@indydevs.org>2023-04-13 04:46:52 (GMT)
committerGitHub <noreply@github.com>2023-04-13 04:46:52 (GMT)
commit19d2639d1e6478e2e251479d842bdfa2e8272396 (patch)
tree56b20f455cc63ee8180cc10141c36aff67c732b5 /Lib
parent9e677406ee6666b32d869ce68c826519ff877445 (diff)
downloadcpython-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.py3
-rw-r--r--Lib/test/test_asyncio/test_selector_events.py42
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()