Fix deadlock when stopping queued script (#68175)

pull/68180/head^2
Erik Montnemery 2022-03-15 16:29:04 +01:00 committed by GitHub
parent cdd23abea7
commit 8ea31cea3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 2 deletions

View File

@ -860,12 +860,13 @@ class _QueuedScriptRun(_ScriptRun):
{lock_task, stop_task}, return_when=asyncio.FIRST_COMPLETED
)
except asyncio.CancelledError:
lock_task.cancel()
self._finish()
raise
else:
self.lock_acquired = lock_task.done() and not lock_task.cancelled()
finally:
lock_task.cancel()
stop_task.cancel()
self.lock_acquired = lock_task.done() and not lock_task.cancelled()
# If we've been told to stop, then just finish up. Otherwise, we've acquired the
# lock so we can go ahead and start the run.

View File

@ -3203,6 +3203,37 @@ async def test_script_mode_queued_cancel(hass):
raise
async def test_script_mode_queued_stop(hass):
"""Test stopping with a queued run."""
script_obj = script.Script(
hass,
cv.SCRIPT_SCHEMA({"wait_template": "{{ false }}"}),
"Test Name",
"test_domain",
script_mode="queued",
max_runs=3,
)
wait_started_flag = async_watch_for_action(script_obj, "wait")
assert not script_obj.is_running
assert script_obj.runs == 0
hass.async_create_task(script_obj.async_run(context=Context()))
await asyncio.wait_for(wait_started_flag.wait(), 1)
hass.async_create_task(script_obj.async_run(context=Context()))
await asyncio.sleep(0)
hass.async_create_task(script_obj.async_run(context=Context()))
await asyncio.sleep(0)
assert script_obj.is_running
assert script_obj.runs == 3
await script_obj.async_stop()
assert not script_obj.is_running
assert script_obj.runs == 0
async def test_script_logging(hass, caplog):
"""Test script logging."""
script_obj = script.Script(hass, [], "Script with % Name", "test_domain")