[Python-checkins] cpython (3.4): Issue #23140, asyncio: Fix cancellation of Process.wait(). Check the state of

victor.stinner python-checkins at python.org
Tue Jan 6 01:15:03 CET 2015


https://hg.python.org/cpython/rev/7c9b9d2514bb
changeset:   94033:7c9b9d2514bb
branch:      3.4
parent:      94031:ddf6b78faed9
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Jan 06 01:13:49 2015 +0100
summary:
  Issue #23140, asyncio: Fix cancellation of Process.wait(). Check the state of
the waiter future before setting its result.

files:
  Lib/asyncio/subprocess.py                |   3 +-
  Lib/test/test_asyncio/test_subprocess.py |  28 ++++++++++++
  2 files changed, 30 insertions(+), 1 deletions(-)


diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py
--- a/Lib/asyncio/subprocess.py
+++ b/Lib/asyncio/subprocess.py
@@ -96,7 +96,8 @@
         returncode = self._transport.get_returncode()
         while self._waiters:
             waiter = self._waiters.popleft()
-            waiter.set_result(returncode)
+            if not waiter.cancelled():
+                waiter.set_result(returncode)
 
 
 class Process:
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -223,6 +223,34 @@
         self.assertEqual(output.rstrip(), b'3')
         self.assertEqual(exitcode, 0)
 
+    def test_cancel_process_wait(self):
+        # Issue #23140: cancel Process.wait()
+
+        @asyncio.coroutine
+        def wait_proc(proc, event):
+            event.set()
+            yield from proc.wait()
+
+        @asyncio.coroutine
+        def cancel_wait():
+            proc = yield from asyncio.create_subprocess_exec(
+                                          *PROGRAM_BLOCKED,
+                                          loop=self.loop)
+
+            # Create an internal future waiting on the process exit
+            event = asyncio.Event(loop=self.loop)
+            task = self.loop.create_task(wait_proc(proc, event))
+            yield from event.wait()
+
+            # Cancel the future
+            task.cancel()
+
+            # Kill the process and wait until it is done
+            proc.kill()
+            yield from proc.wait()
+
+        self.loop.run_until_complete(cancel_wait())
+
 
 if sys.platform != 'win32':
     # Unix

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


More information about the Python-checkins mailing list