Fix deadlock when restarting scripts (#49410)

This commit is contained in:
Erik Montnemery 2021-04-19 14:45:01 +02:00 committed by Franck Nijhof
parent 7ed8f00075
commit a5a62154d4
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3

View File

@ -1203,12 +1203,9 @@ class Script:
self._changed() self._changed()
raise raise
async def _async_stop(self, update_state, spare=None): async def _async_stop(
aws = [ self, aws: list[asyncio.Task], update_state: bool, spare: _ScriptRun | None
asyncio.create_task(run.async_stop()) for run in self._runs if run != spare ) -> None:
]
if not aws:
return
await asyncio.wait(aws) await asyncio.wait(aws)
if update_state: if update_state:
self._changed() self._changed()
@ -1217,7 +1214,15 @@ class Script:
self, update_state: bool = True, spare: _ScriptRun | None = None self, update_state: bool = True, spare: _ScriptRun | None = None
) -> None: ) -> None:
"""Stop running script.""" """Stop running script."""
await asyncio.shield(self._async_stop(update_state, spare)) # Collect a a list of script runs to stop. This must be done before calling
# asyncio.shield as asyncio.shield yields to the event loop, which would cause
# us to wait for script runs added after the call to async_stop.
aws = [
asyncio.create_task(run.async_stop()) for run in self._runs if run != spare
]
if not aws:
return
await asyncio.shield(self._async_stop(aws, update_state, spare))
async def _async_get_condition(self, config): async def _async_get_condition(self, config):
if isinstance(config, template.Template): if isinstance(config, template.Template):