summaryrefslogtreecommitdiff
path: root/Lib/asyncio/protocols.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-06-08 00:25:52 +0200
committerGitHub <noreply@github.com>2018-06-08 00:25:52 +0200
commit79790bc35fe722a49977b52647f9b5fe1deda2b7 (patch)
treeb1b3da290ccfb7055c94e937cd1edc0282bf7a38 /Lib/asyncio/protocols.py
parentd3ed67d14ed401dfe2b5d07b6941adc3ecacb268 (diff)
downloadcpython-git-79790bc35fe722a49977b52647f9b5fe1deda2b7.tar.gz
bpo-33694: Fix race condition in asyncio proactor (GH-7498)
The cancellation of an overlapped WSARecv() has a race condition which causes data loss because of the current implementation of proactor in asyncio. No longer cancel overlapped WSARecv() in _ProactorReadPipeTransport to work around the race condition. Remove the optimized recv_into() implementation to get simple implementation of pause_reading() using the single _pending_data attribute. Move _feed_data_to_bufferred_proto() to protocols.py. Remove set_protocol() method which became useless.
Diffstat (limited to 'Lib/asyncio/protocols.py')
-rw-r--r--Lib/asyncio/protocols.py19
1 files changed, 19 insertions, 0 deletions
diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py
index b8d2e6be55..4d47da387c 100644
--- a/Lib/asyncio/protocols.py
+++ b/Lib/asyncio/protocols.py
@@ -189,3 +189,22 @@ class SubprocessProtocol(BaseProtocol):
def process_exited(self):
"""Called when subprocess has exited."""
+
+
+def _feed_data_to_bufferred_proto(proto, data):
+ data_len = len(data)
+ while data_len:
+ buf = proto.get_buffer(data_len)
+ buf_len = len(buf)
+ if not buf_len:
+ raise RuntimeError('get_buffer() returned an empty buffer')
+
+ if buf_len >= data_len:
+ buf[:data_len] = data
+ proto.buffer_updated(data_len)
+ return
+ else:
+ buf[:buf_len] = data[:buf_len]
+ proto.buffer_updated(buf_len)
+ data = data[buf_len:]
+ data_len = len(data)