summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_asyncio/test_windows_events.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-07-24 22:54:53 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-07-24 22:54:53 (GMT)
commitfea6a100dc51012cb0187374ad31de330ebc0035 (patch)
treed08433104303f217e1e3798fb43b398cec09b07d /Lib/test/test_asyncio/test_windows_events.py
parent92639cce354ecb52db6179c3edcf90012096f345 (diff)
downloadcpython-fea6a100dc51012cb0187374ad31de330ebc0035.zip
cpython-fea6a100dc51012cb0187374ad31de330ebc0035.tar.gz
cpython-fea6a100dc51012cb0187374ad31de330ebc0035.tar.bz2
asyncio: sync with Tulip
Improve stability of the proactor event loop, especially operations on overlapped objects: * Tulip issue 195: Don't call UnregisterWait() twice if a _WaitHandleFuture is cancelled twice to fix a crash. * IocpProactor.close(): cancel futures to cancel overlapped operations, instead of cancelling directly overlapped operations. Future objects may not call ov.cancel() if the future was cancelled or if the overlapped was already cancelled. The cancel() method of the future may also catch exceptions. Log also errors on cancellation. * tests: rename "f" to "fut" * Add a __repr__() method to IocpProactor * Add a destructor to IocpProactor which closes it * _OverlappedFuture.cancel() doesn't cancel the overlapped anymore if it is done: if it is already cancelled or completed. Log also an error if the cancellation failed. * Add the address of the overlapped object in repr(_OverlappedFuture) * _OverlappedFuture truncates the source traceback to hide the call to the parent constructor (useless in debug).
Diffstat (limited to 'Lib/test/test_asyncio/test_windows_events.py')
-rw-r--r--Lib/test/test_asyncio/test_windows_events.py30
1 files changed, 20 insertions, 10 deletions
diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py
index 689deb4..85d9669 100644
--- a/Lib/test/test_asyncio/test_windows_events.py
+++ b/Lib/test/test_asyncio/test_windows_events.py
@@ -96,36 +96,46 @@ class ProactorTests(test_utils.TestCase):
# Wait for unset event with 0.5s timeout;
# result should be False at timeout
- f = self.loop._proactor.wait_for_handle(event, 0.5)
+ fut = self.loop._proactor.wait_for_handle(event, 0.5)
start = self.loop.time()
- self.loop.run_until_complete(f)
+ self.loop.run_until_complete(fut)
elapsed = self.loop.time() - start
- self.assertFalse(f.result())
+ self.assertFalse(fut.result())
self.assertTrue(0.48 < elapsed < 0.9, elapsed)
_overlapped.SetEvent(event)
# Wait for for set event;
# result should be True immediately
- f = self.loop._proactor.wait_for_handle(event, 10)
+ fut = self.loop._proactor.wait_for_handle(event, 10)
start = self.loop.time()
- self.loop.run_until_complete(f)
+ self.loop.run_until_complete(fut)
elapsed = self.loop.time() - start
- self.assertTrue(f.result())
+ self.assertTrue(fut.result())
self.assertTrue(0 <= elapsed < 0.3, elapsed)
- _overlapped.ResetEvent(event)
+ # Tulip issue #195: cancelling a done _WaitHandleFuture must not crash
+ fut.cancel()
+
+ def test_wait_for_handle_cancel(self):
+ event = _overlapped.CreateEvent(None, True, False, None)
+ self.addCleanup(_winapi.CloseHandle, event)
# Wait for unset event with a cancelled future;
# CancelledError should be raised immediately
- f = self.loop._proactor.wait_for_handle(event, 10)
- f.cancel()
+ fut = self.loop._proactor.wait_for_handle(event, 10)
+ fut.cancel()
start = self.loop.time()
with self.assertRaises(asyncio.CancelledError):
- self.loop.run_until_complete(f)
+ self.loop.run_until_complete(fut)
elapsed = self.loop.time() - start
self.assertTrue(0 <= elapsed < 0.1, elapsed)
+ # Tulip issue #195: cancelling a _WaitHandleFuture twice must not crash
+ fut = self.loop._proactor.wait_for_handle(event)
+ fut.cancel()
+ fut.cancel()
+
if __name__ == '__main__':
unittest.main()