summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-01-26 22:13:20 +0100
committerVictor Stinner <victor.stinner@gmail.com>2015-01-26 22:13:20 +0100
commit6e1910bb8aaa1149bb7ebb7aba3c0c73a5522262 (patch)
tree36fe49b812feee962ba18a7d2c2ff0f6b6c2e620
parent69c97945d0a85c73442e76da72f37d9c7f525dba (diff)
downloadtrollius-6e1910bb8aaa1149bb7ebb7aba3c0c73a5522262.tar.gz
Python issue #23095: 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.
-rw-r--r--asyncio/windows_events.py37
1 files changed, 17 insertions, 20 deletions
diff --git a/asyncio/windows_events.py b/asyncio/windows_events.py
index c9ba785..8f1d9d2 100644
--- a/asyncio/windows_events.py
+++ b/asyncio/windows_events.py
@@ -126,14 +126,12 @@ class _BaseWaitHandleFuture(futures.Future):
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 @@ class _BaseWaitHandleFuture(futures.Future):
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 @@ class _WaitHandleFuture(_BaseWaitHandleFuture):
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 @@ class _WaitHandleFuture(_BaseWaitHandleFuture):
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):