mirror of https://github.com/python/cpython
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()
|
returncode = self._transport.get_returncode()
|
||||||
while self._waiters:
|
while self._waiters:
|
||||||
waiter = self._waiters.popleft()
|
waiter = self._waiters.popleft()
|
||||||
waiter.set_result(returncode)
|
if not waiter.cancelled():
|
||||||
|
waiter.set_result(returncode)
|
||||||
|
|
||||||
|
|
||||||
class Process:
|
class Process:
|
||||||
|
|
|
@ -223,6 +223,34 @@ class SubprocessMixin:
|
||||||
self.assertEqual(output.rstrip(), b'3')
|
self.assertEqual(output.rstrip(), b'3')
|
||||||
self.assertEqual(exitcode, 0)
|
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':
|
if sys.platform != 'win32':
|
||||||
# Unix
|
# Unix
|
||||||
|
|
Loading…
Reference in New Issue