Issue #23140, asyncio: Fix cancellation of Process.wait(). Check the state of
the waiter future before setting its result.
This commit is contained in:
parent
8c1a4a2326
commit
c447ba04e7
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue