Issue #23140, asyncio: Fix cancellation of Process.wait(). Check the state of

the waiter future before setting its result.
This commit is contained in:
Victor Stinner 2015-01-06 01:13:49 +01:00
parent 8c1a4a2326
commit c447ba04e7
2 changed files with 30 additions and 1 deletions

View File

@ -96,7 +96,8 @@ class SubprocessStreamProtocol(streams.FlowControlMixin,
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:

View File

@ -223,6 +223,34 @@ class SubprocessMixin:
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