aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/PySide6/QtAsyncio/tasks.py
diff options
context:
space:
mode:
authorAdrian Herrmann <adrian.herrmann@qt.io>2024-04-19 23:23:48 +0200
committerAdrian Herrmann <adrian.herrmann@qt.io>2024-04-22 15:13:28 +0200
commit9de4dee2f697dc88812dfad04ce4054cebf6be61 (patch)
treea34bd93dc52ea6f3230724f085d5160a5efe2e80 /sources/pyside6/PySide6/QtAsyncio/tasks.py
parentb27e1e5fe85ad7697ebbd571d1097ff656503803 (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.py11
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: