[Python-checkins] cpython (3.4): Issue #23095, asyncio: Fix _WaitHandleFuture.cancel()

victor.stinner python-checkins at python.org
Mon Jan 26 22:32:34 CET 2015


https://hg.python.org/cpython/rev/36e80c6599aa
changeset:   94323:36e80c6599aa
branch:      3.4
parent:      94318:99c3e304a4ea
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Mon Jan 26 22:30:28 2015 +0100
summary:
  Issue #23095, asyncio: Fix _WaitHandleFuture.cancel()

If UnregisterWaitEx() fais with ERROR_IO_PENDING, it doesn't mean that the wait
is unregistered yet. We still have to wait until the wait is cancelled.

files:
  Lib/asyncio/windows_events.py |  37 ++++++++++------------
  1 files changed, 17 insertions(+), 20 deletions(-)


diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py
--- a/Lib/asyncio/windows_events.py
+++ b/Lib/asyncio/windows_events.py
@@ -126,14 +126,12 @@
             return
         self._registered = False
 
+        wait_handle = self._wait_handle
+        self._wait_handle = None
         try:
-            _overlapped.UnregisterWait(self._wait_handle)
+            _overlapped.UnregisterWait(wait_handle)
         except OSError as exc:
-            self._wait_handle = None
-            if exc.winerror == _overlapped.ERROR_IO_PENDING:
-                # ERROR_IO_PENDING is not an error, the wait was unregistered
-                self._unregister_wait_cb(None)
-            elif exc.winerror != _overlapped.ERROR_IO_PENDING:
+            if exc.winerror != _overlapped.ERROR_IO_PENDING:
                 context = {
                     'message': 'Failed to unregister the wait handle',
                     'exception': exc,
@@ -142,9 +140,10 @@
                 if self._source_traceback:
                     context['source_traceback'] = self._source_traceback
                 self._loop.call_exception_handler(context)
-        else:
-            self._wait_handle = None
-            self._unregister_wait_cb(None)
+                return
+            # ERROR_IO_PENDING means that the unregister is pending
+
+        self._unregister_wait_cb(None)
 
     def cancel(self):
         self._unregister_wait()
@@ -209,14 +208,12 @@
             return
         self._registered = False
 
+        wait_handle = self._wait_handle
+        self._wait_handle = None
         try:
-            _overlapped.UnregisterWaitEx(self._wait_handle, self._event)
+            _overlapped.UnregisterWaitEx(wait_handle, self._event)
         except OSError as exc:
-            self._wait_handle = None
-            if exc.winerror == _overlapped.ERROR_IO_PENDING:
-                # ERROR_IO_PENDING is not an error, the wait was unregistered
-                self._unregister_wait_cb(None)
-            elif exc.winerror != _overlapped.ERROR_IO_PENDING:
+            if exc.winerror != _overlapped.ERROR_IO_PENDING:
                 context = {
                     'message': 'Failed to unregister the wait handle',
                     'exception': exc,
@@ -225,11 +222,11 @@
                 if self._source_traceback:
                     context['source_traceback'] = self._source_traceback
                 self._loop.call_exception_handler(context)
-        else:
-            self._wait_handle = None
-            self._event_fut = self._proactor._wait_cancel(
-                                                self._event,
-                                                self._unregister_wait_cb)
+                return
+            # ERROR_IO_PENDING is not an error, the wait was unregistered
+
+        self._event_fut = self._proactor._wait_cancel(self._event,
+                                                      self._unregister_wait_cb)
 
 
 class PipeServer(object):

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list