diff options
| author | Adrian Herrmann <adrian.herrmann@qt.io> | 2024-04-19 23:23:48 +0200 |
|---|---|---|
| committer | Adrian Herrmann <adrian.herrmann@qt.io> | 2024-04-22 15:13:28 +0200 |
| commit | 9de4dee2f697dc88812dfad04ce4054cebf6be61 (patch) | |
| tree | a34bd93dc52ea6f3230724f085d5160a5efe2e80 /sources/pyside6/PySide6/QtAsyncio/tasks.py | |
| parent | b27e1e5fe85ad7697ebbd571d1097ff656503803 (diff) | |
QtAsyncio: Fix tasks with loop not cancelling
If a task was cancelled, then a new future created from this task should
be cancelled as well. Otherwise, in some scenarios like a loop inside
the task and with bad timing, if the new future is not cancelled, the
task would continue running in this loop despite having been cancelled.
This bad timing can occur especially if the first future finishes very
quickly.
Pick-to: 6.7
Fixes: PYSIDE-2644
Task-number: PYSIDE-769
Change-Id: Icfff6e4ad5da565f50e3d89fbf85d1fecbf93650
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside6/PySide6/QtAsyncio/tasks.py')
| -rw-r--r-- | sources/pyside6/PySide6/QtAsyncio/tasks.py | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/sources/pyside6/PySide6/QtAsyncio/tasks.py b/sources/pyside6/PySide6/QtAsyncio/tasks.py index bc3d41a73..6777b8bc3 100644 --- a/sources/pyside6/PySide6/QtAsyncio/tasks.py +++ b/sources/pyside6/PySide6/QtAsyncio/tasks.py @@ -29,6 +29,7 @@ class QAsyncioTask(futures.QAsyncioFuture): self._future_to_await: typing.Optional[asyncio.Future] = None self._cancel_message: typing.Optional[str] = None + self._cancelled = False asyncio._register_task(self) # type: ignore[arg-type] @@ -90,6 +91,15 @@ class QAsyncioTask(futures.QAsyncioFuture): result.add_done_callback( self._step, context=self._context) # type: ignore[arg-type] self._future_to_await = result + if self._cancelled: + # If the task was cancelled, then a new future should be + # cancelled as well. Otherwise, in some scenarios like + # a loop inside the task and with bad timing, if the new + # future is not cancelled, the task would continue running + # in this loop despite having been cancelled. This bad + # timing can occur especially if the first future finishes + # very quickly. + self._future_to_await.cancel(self._cancel_message) elif result is None: self._loop.call_soon(self._step, context=self._context) else: @@ -136,6 +146,7 @@ class QAsyncioTask(futures.QAsyncioFuture): self._handle.cancel() if self._future_to_await is not None: self._future_to_await.cancel(msg) + self._cancelled = True return True def uncancel(self) -> None: |
