Skip to content

Commit 71b8fb8

Browse files
deadlovelllmiss-islington
authored andcommitted
gh-155888: Fix asyncio writelines() hanging on an empty chunk (GH-155889)
(cherry picked from commit b2c2993) Co-authored-by: Timofei Ivankov <128279579+deadlovelll@users.noreply.github.com>
1 parent 39a0217 commit 71b8fb8

3 files changed

Lines changed: 20 additions & 0 deletions

File tree

Lib/asyncio/selector_events.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,8 +1197,13 @@ def writelines(self, list_of_data):
11971197
return
11981198

11991199
for data in list_of_data:
1200+
# gh-155888: an empty chunk can never be drained, so never buffer it
1201+
if not data:
1202+
continue
12001203
self._buffer.append(memoryview(data))
12011204
self._buffer_size += len(data)
1205+
if not self._buffer:
1206+
return
12021207
self._write_ready()
12031208
# If the entire buffer couldn't be written, register a write handler
12041209
if self._buffer:

Lib/test/test_asyncio/test_events.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,19 @@ def writer(data):
560560
r.close()
561561
self.assertEqual(read, data)
562562

563+
def test_writelines_empty_chunk(self):
564+
# gh-155888: an empty chunk can never be drained, so never buffer it
565+
rsock, wsock = socket.socketpair()
566+
self.addCleanup(rsock.close)
567+
568+
async def main():
569+
reader, writer = await asyncio.open_connection(sock=wsock)
570+
writer.writelines([b'data', b''])
571+
writer.close()
572+
await asyncio.wait_for(writer.wait_closed(), support.SHORT_TIMEOUT)
573+
574+
self.loop.run_until_complete(main())
575+
563576
@unittest.skipUnless(hasattr(signal, 'SIGKILL'), 'No SIGKILL')
564577
def test_add_signal_handler(self):
565578
caught = 0
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :meth:`asyncio.WriteTransport.writelines` hanging the transport when the
2+
last data chunk is empty.

0 commit comments

Comments
 (0)