diff options
author | Guido van Rossum <guido@python.org> | 2014-05-12 17:04:37 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2014-05-12 17:04:37 (GMT) |
commit | bf88ffba5edf780e12a64db9cb929216c19f6cfa (patch) | |
tree | 8ee2815214e6848e7e3e909151a43ea552189157 /Lib/asyncio/streams.py | |
parent | a869fd3dc0117d2f02fb7e4146b6c446a68eaeb4 (diff) | |
download | cpython-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.py | 17 |
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') |