[Python-checkins] cpython: asyncio: Fix deadlock in readexactly(). Fixes issue #20154.

guido.van.rossum python-checkins at python.org
Tue Jan 7 01:09:30 CET 2014


http://hg.python.org/cpython/rev/54d32e01bbfd
changeset: 88329:54d32e01bbfd
user: Guido van Rossum <guido at python.org>
date: Mon Jan 06 16:09:18 2014 -0800
summary:
 asyncio: Fix deadlock in readexactly(). Fixes issue #20154.
files:
 Lib/asyncio/streams.py | 29 +++++++++++++++++++----------
 Misc/NEWS | 2 ++
 2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -220,6 +220,7 @@
 if loop is None:
 loop = events.get_event_loop()
 self._loop = loop
+ # TODO: Use a bytearray for a buffer, like the transport.
 self._buffer = collections.deque() # Deque of bytes objects.
 self._byte_count = 0 # Bytes in buffer.
 self._eof = False # Whether we're done.
@@ -384,15 +385,23 @@
 if self._exception is not None:
 raise self._exception
 
- if n <= 0:
- return b''
+ # There used to be "optimized" code here. It created its own
+ # Future and waited until self._buffer had at least the n
+ # bytes, then called read(n). Unfortunately, this could pause
+ # the transport if the argument was larger than the pause
+ # limit (which is twice self._limit). So now we just read()
+ # into a local buffer.
 
- while self._byte_count < n and not self._eof:
- assert not self._waiter
- self._waiter = futures.Future(loop=self._loop)
- try:
- yield from self._waiter
- finally:
- self._waiter = None
+ blocks = []
+ while n > 0:
+ block = yield from self.read(n)
+ if not block:
+ break
+ blocks.append(block)
+ n -= len(block)
 
- return (yield from self.read(n))
+ # TODO: Raise EOFError if we break before n == 0? (That would
+ # be a change in specification, but I've always had to add an
+ # explicit size check to the caller.)
+
+ return b''.join(blocks)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -75,6 +75,8 @@
 Library
 -------
 
+- Issue #20154: Deadlock in asyncio.StreamReader.readexactly().
+
 - Issue #16113: Remove sha3 module again.
 
 - Issue #20111: pathlib.Path.with_suffix() now sanity checks the given suffix.
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /