diff options
| author | Victor Stinner <victor.stinner@gmail.com> | 2015-01-22 21:55:31 (GMT) | 
|---|---|---|
| committer | Victor Stinner <victor.stinner@gmail.com> | 2015-01-22 21:55:31 (GMT) | 
| commit | 58c85144db694508573fde2dc1df1b5ec12a7677 (patch) | |
| tree | 6a43e807cd63202857af9a354c652118af6d2903 /Lib/asyncio/windows_events.py | |
| parent | 8eef090bb6c038ea4f68fb01998ecdd7b2cfde01 (diff) | |
| parent | 7ffa2c5fdda8a9cc254edf67c4458b15db1252fa (diff) | |
| download | cpython-58c85144db694508573fde2dc1df1b5ec12a7677.zip cpython-58c85144db694508573fde2dc1df1b5ec12a7677.tar.gz cpython-58c85144db694508573fde2dc1df1b5ec12a7677.tar.bz2 | |
Merge 3.4 (asyncio)
Diffstat (limited to 'Lib/asyncio/windows_events.py')
| -rw-r--r-- | Lib/asyncio/windows_events.py | 53 | 
1 files changed, 33 insertions, 20 deletions
| diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 3cb5690f..7d0dbe9 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -29,6 +29,12 @@ INFINITE = 0xffffffff  ERROR_CONNECTION_REFUSED = 1225  ERROR_CONNECTION_ABORTED = 1236 +# Initial delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_INIT_DELAY = 0.001 + +# Maximum delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_MAX_DELAY = 0.100 +  class _OverlappedFuture(futures.Future):      """Subclass of Future which represents an overlapped operation. @@ -495,25 +501,28 @@ class IocpProactor:          return self._register(ov, pipe, finish_accept_pipe,                                register=False) -    def connect_pipe(self, address): -        ov = _overlapped.Overlapped(NULL) -        ov.WaitNamedPipeAndConnect(address, self._iocp, ov.address) - -        def finish_connect_pipe(err, handle, ov): -            # err, handle were arguments passed to PostQueuedCompletionStatus() -            # in a function run in a thread pool. -            if err == _overlapped.ERROR_SEM_TIMEOUT: -                # Connection did not succeed within time limit. -                msg = _overlapped.FormatMessage(err) -                raise ConnectionRefusedError(0, msg, None, err) -            elif err != 0: -                msg = _overlapped.FormatMessage(err) -                raise OSError(0, msg, None, err) +    def _connect_pipe(self, fut, address, delay): +        # Unfortunately there is no way to do an overlapped connect to a pipe. +        # Call CreateFile() in a loop until it doesn't fail with +        # ERROR_PIPE_BUSY +        try: +            handle = _overlapped.ConnectPipe(address) +        except OSError as exc: +            if exc.winerror == _overlapped.ERROR_PIPE_BUSY: +                # Polling: retry later +                delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY) +                self._loop.call_later(delay, +                                      self._connect_pipe, fut, address, delay)              else: -                return windows_utils.PipeHandle(handle) +                fut.set_exception(exc) +        else: +            pipe = windows_utils.PipeHandle(handle) +            fut.set_result(pipe) -        return self._register(ov, None, finish_connect_pipe, -                              wait_for_post=True) +    def connect_pipe(self, address): +        fut = futures.Future(loop=self._loop) +        self._connect_pipe(fut, address, CONNECT_PIPE_INIT_DELAY) +        return fut      def wait_for_handle(self, handle, timeout=None):          """Wait for a handle. @@ -693,12 +702,16 @@ class IocpProactor:                  # queues a task to Windows' thread pool.  This cannot                  # be cancelled, so just forget it.                  del self._cache[address] -            # FIXME: Tulip issue 196: remove this case, it should not happen -            elif fut.done() and not fut.cancelled(): -                del self._cache[address] +            elif fut.cancelled(): +                # Nothing to do with cancelled futures +                pass              elif isinstance(fut, _WaitCancelFuture):                  # _WaitCancelFuture must not be cancelled                  pass +            elif fut.done(): +                # FIXME: Tulip issue 196: remove this case, it should not +                # happen +                del self._cache[address]              else:                  try:                      fut.cancel() | 
