Skip to content

Commit 2b77c54

Browse files
committed
asyncio, Tulip issue 204: Fix IocpProactor.accept_pipe()
Overlapped.ConnectNamedPipe() now returns a boolean: True if the pipe is connected (if ConnectNamedPipe() failed with ERROR_PIPE_CONNECTED), False if the connection is in progress. This change removes multiple hacks in IocpProactor.
1 parent 34cd2ae commit 2b77c54

2 files changed

Lines changed: 19 additions & 26 deletions

File tree

‎Lib/asyncio/windows_events.py‎

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,21 @@ def finish_connect(trans, key, ov):
490490
def accept_pipe(self, pipe):
491491
self._register_with_iocp(pipe)
492492
ov = _overlapped.Overlapped(NULL)
493-
ov.ConnectNamedPipe(pipe.fileno())
493+
connected = ov.ConnectNamedPipe(pipe.fileno())
494+
495+
if connected:
496+
# ConnectNamePipe() failed with ERROR_PIPE_CONNECTED which means
497+
# that the pipe is connected. There is no need to wait for the
498+
# completion of the connection.
499+
f = futures.Future(loop=self._loop)
500+
f.set_result(pipe)
501+
return f
494502

495503
def finish_accept_pipe(trans, key, ov):
496504
ov.getresult()
497505
return pipe
498506

499-
# FIXME: Tulip issue 196: why do we need register=False?
500-
# See also the comment in the _register() method
501-
return self._register(ov, pipe, finish_accept_pipe,
502-
register=False)
507+
return self._register(ov, pipe, finish_accept_pipe)
503508

504509
def _connect_pipe(self, fut, address, delay):
505510
# Unfortunately there is no way to do an overlapped connect to a pipe.
@@ -581,15 +586,14 @@ def _register_with_iocp(self, obj):
581586
# to avoid sending notifications to completion port of ops
582587
# that succeed immediately.
583588

584-
def _register(self, ov, obj, callback,
585-
wait_for_post=False, register=True):
589+
def _register(self, ov, obj, callback):
586590
# Return a future which will be set with the result of the
587591
# operation when it completes. The future's value is actually
588592
# the value returned by callback().
589593
f = _OverlappedFuture(ov, loop=self._loop)
590594
if f._source_traceback:
591595
del f._source_traceback[-1]
592-
if not ov.pending and not wait_for_post:
596+
if not ov.pending:
593597
# The operation has completed, so no need to postpone the
594598
# work. We cannot take this short cut if we need the
595599
# NumberOfBytes, CompletionKey values returned by
@@ -605,18 +609,11 @@ def _register(self, ov, obj, callback,
605609
# Register the overlapped operation to keep a reference to the
606610
# OVERLAPPED object, otherwise the memory is freed and Windows may
607611
# read uninitialized memory.
608-
#
609-
# For an unknown reason, ConnectNamedPipe() behaves differently:
610-
# the completion is not notified by GetOverlappedResult() if we
611-
# already called GetOverlappedResult(). For this specific case, we
612-
# don't expect notification (register is set to False).
613-
else:
614-
register = True
615-
if register:
616-
# Register the overlapped operation for later. Note that
617-
# we only store obj to prevent it from being garbage
618-
# collected too early.
619-
self._cache[ov.address] = (f, ov, obj, callback)
612+
613+
# Register the overlapped operation for later. Note that
614+
# we only store obj to prevent it from being garbage
615+
# collected too early.
616+
self._cache[ov.address] = (f, ov, obj, callback)
620617
return f
621618

622619
def _unregister(self, ov):
@@ -708,10 +705,6 @@ def close(self):
708705
elif isinstance(fut, _WaitCancelFuture):
709706
# _WaitCancelFuture must not be cancelled
710707
pass
711-
elif fut.done():
712-
# FIXME: Tulip issue 196: remove this case, it should not
713-
# happen
714-
del self._cache[address]
715708
else:
716709
try:
717710
fut.cancel()

‎Modules/overlapped.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,10 +1117,10 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args)
11171117
switch (err) {
11181118
case ERROR_PIPE_CONNECTED:
11191119
mark_as_completed(&self->overlapped);
1120-
Py_RETURN_NONE;
1120+
Py_RETURN_TRUE;
11211121
case ERROR_SUCCESS:
11221122
case ERROR_IO_PENDING:
1123-
Py_RETURN_NONE;
1123+
Py_RETURN_FALSE;
11241124
default:
11251125
self->type = TYPE_NOT_STARTED;
11261126
return SetFromWindowsErr(err);

0 commit comments

Comments
 (0)