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().
This commit is contained in:
Victor Stinner 2015-01-26 22:30:49 +01:00
parent 24dfa3c1d6
commit 41063d2a59
2 changed files with 15 additions and 9 deletions

View File

@ -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)
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()

View File

@ -730,7 +730,7 @@ Overlapped_ReadFile(OverlappedObject *self, PyObject *args)
switch (err) {
case ERROR_BROKEN_PIPE:
mark_as_completed(&self->overlapped);
Py_RETURN_NONE;
return SetFromWindowsErr(err);
case ERROR_SUCCESS:
case ERROR_MORE_DATA:
case ERROR_IO_PENDING:
@ -789,7 +789,7 @@ Overlapped_WSARecv(OverlappedObject *self, PyObject *args)
switch (err) {
case ERROR_BROKEN_PIPE:
mark_as_completed(&self->overlapped);
Py_RETURN_NONE;
return SetFromWindowsErr(err);
case ERROR_SUCCESS:
case ERROR_MORE_DATA:
case ERROR_IO_PENDING: