summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-01-26 21:30:28 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-01-26 21:30:28 (GMT)
commit24dfa3c1d6b21e731bd167a13153968bba8fa5ce (patch)
treee1f6c275df8b4d380d54062b2ccddc44adcb6c05 /Lib/asyncio
parente0fd157ba0cc92e435e7520b4ff641ca68d72244 (diff)
downloadcpython-24dfa3c1d6b21e731bd167a13153968bba8fa5ce.zip
cpython-24dfa3c1d6b21e731bd167a13153968bba8fa5ce.tar.gz
cpython-24dfa3c1d6b21e731bd167a13153968bba8fa5ce.tar.bz2
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.
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/windows_events.py37
1 files changed, 17 insertions, 20 deletions
diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py
index c9ba785..8f1d9d2 100644
--- a/Lib/asyncio/windows_events.py
+++ b/Lib/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):