summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/streams.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2014-05-12 17:04:37 (GMT)
committerGuido van Rossum <guido@python.org>2014-05-12 17:04:37 (GMT)
commitbf88ffba5edf780e12a64db9cb929216c19f6cfa (patch)
tree8ee2815214e6848e7e3e909151a43ea552189157 /Lib/asyncio/streams.py
parenta869fd3dc0117d2f02fb7e4146b6c446a68eaeb4 (diff)
downloadcpython-bf88ffba5edf780e12a64db9cb929216c19f6cfa.zip
cpython-bf88ffba5edf780e12a64db9cb929216c19f6cfa.tar.gz
cpython-bf88ffba5edf780e12a64db9cb929216c19f6cfa.tar.bz2
asyncio: Fix upstream issue 168: StreamReader.read(-1) from pipe may hang if data exceeds buffer limit.
Diffstat (limited to 'Lib/asyncio/streams.py')
-rw-r--r--Lib/asyncio/streams.py17
1 files changed, 11 insertions, 6 deletions
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
index 27d595f..e239248 100644
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -419,12 +419,17 @@ class StreamReader:
return b''
if n < 0:
- while not self._eof:
- self._waiter = self._create_waiter('read')
- try:
- yield from self._waiter
- finally:
- self._waiter = None
+ # This used to just loop creating a new waiter hoping to
+ # collect everything in self._buffer, but that would
+ # deadlock if the subprocess sends more than self.limit
+ # bytes. So just call self.read(self._limit) until EOF.
+ blocks = []
+ while True:
+ block = yield from self.read(self._limit)
+ if not block:
+ break
+ blocks.append(block)
+ return b''.join(blocks)
else:
if not self._buffer and not self._eof:
self._waiter = self._create_waiter('read')