diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-01-26 21:30:49 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-01-26 21:30:49 (GMT) |
commit | 41063d2a59a24e257cd9ce62137e36c862e3ab1e (patch) | |
tree | 65f8861d33e1cdd09058f464a5ad162a80bffc69 /Lib/asyncio | |
parent | 24dfa3c1d6b21e731bd167a13153968bba8fa5ce (diff) | |
download | cpython-41063d2a59a24e257cd9ce62137e36c862e3ab1e.zip cpython-41063d2a59a24e257cd9ce62137e36c862e3ab1e.tar.gz cpython-41063d2a59a24e257cd9ce62137e36c862e3ab1e.tar.bz2 |
asyncio, Tulip issue 204: Fix IocpProactor.recv()
If ReadFile() fails with ERROR_BROKEN_PIPE, the operation is not pending: don't
register the overlapped.
I don't know if WSARecv() can fail with ERROR_BROKEN_PIPE. Since
Overlapped.WSARecv() already handled ERROR_BROKEN_PIPE, let me guess that it
has the same behaviour than ReadFile().
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/windows_events.py | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 8f1d9d2..94aafb6 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -406,13 +406,21 @@ class IocpProactor: self._results = [] return tmp + def _result(self, value): + fut = futures.Future(loop=self._loop) + fut.set_result(value) + return fut + def recv(self, conn, nbytes, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) - if isinstance(conn, socket.socket): - ov.WSARecv(conn.fileno(), nbytes, flags) - else: - ov.ReadFile(conn.fileno(), nbytes) + try: + if isinstance(conn, socket.socket): + ov.WSARecv(conn.fileno(), nbytes, flags) + else: + ov.ReadFile(conn.fileno(), nbytes) + except BrokenPipeError: + return self._result(b'') def finish_recv(trans, key, ov): try: @@ -505,9 +513,7 @@ class IocpProactor: # ConnectNamePipe() failed with ERROR_PIPE_CONNECTED which means # that the pipe is connected. There is no need to wait for the # completion of the connection. - f = futures.Future(loop=self._loop) - f.set_result(pipe) - return f + return self._result(pipe) def finish_accept_pipe(trans, key, ov): ov.getresult() |