Fix deadlock when stopping queued script (#68175)
parent
cdd23abea7
commit
8ea31cea3a
|
@ -860,12 +860,13 @@ class _QueuedScriptRun(_ScriptRun):
|
||||||
{lock_task, stop_task}, return_when=asyncio.FIRST_COMPLETED
|
{lock_task, stop_task}, return_when=asyncio.FIRST_COMPLETED
|
||||||
)
|
)
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
lock_task.cancel()
|
|
||||||
self._finish()
|
self._finish()
|
||||||
raise
|
raise
|
||||||
|
else:
|
||||||
|
self.lock_acquired = lock_task.done() and not lock_task.cancelled()
|
||||||
finally:
|
finally:
|
||||||
|
lock_task.cancel()
|
||||||
stop_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
|
# 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.
|
# lock so we can go ahead and start the run.
|
||||||
|
|
|
@ -3203,6 +3203,37 @@ async def test_script_mode_queued_cancel(hass):
|
||||||
raise
|
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):
|
async def test_script_logging(hass, caplog):
|
||||||
"""Test script logging."""
|
"""Test script logging."""
|
||||||
script_obj = script.Script(hass, [], "Script with % Name", "test_domain")
|
script_obj = script.Script(hass, [], "Script with % Name", "test_domain")
|
||||||
|
|
Loading…
Reference in New Issue