aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/_emerge/AsynchronousTask.py2
-rw-r--r--lib/portage/tests/util/futures/test_done_callback_after_exit.py40
2 files changed, 42 insertions, 0 deletions
diff --git a/lib/_emerge/AsynchronousTask.py b/lib/_emerge/AsynchronousTask.py
index 799e66a4a..97db02587 100644
--- a/lib/_emerge/AsynchronousTask.py
+++ b/lib/_emerge/AsynchronousTask.py
@@ -176,6 +176,8 @@ class AsynchronousTask(SlotObject):
if self._exit_listeners is None:
self._exit_listeners = []
self._exit_listeners.append(f)
+ if self.returncode is not None:
+ self._wait_hook()
def removeExitListener(self, f):
if self._exit_listeners is not None:
diff --git a/lib/portage/tests/util/futures/test_done_callback_after_exit.py b/lib/portage/tests/util/futures/test_done_callback_after_exit.py
new file mode 100644
index 000000000..46a51c271
--- /dev/null
+++ b/lib/portage/tests/util/futures/test_done_callback_after_exit.py
@@ -0,0 +1,40 @@
+# Copyright 2020 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from _emerge.AsynchronousTask import AsynchronousTask
+from portage.tests import TestCase
+from portage.util.futures import asyncio
+
+
+class DoneCallbackAfterExitTestCase(TestCase):
+
+ def test_done_callback_after_exit(self):
+ """
+ Test that callbacks can be registered via the Future
+ add_done_callback method even after the future is done, and
+ verify that the callbacks are called.
+ """
+ loop = asyncio._wrap_loop()
+ future = loop.create_future()
+ future.set_result(None)
+
+ for i in range(3):
+ event = loop.create_future()
+ future.add_done_callback(lambda future: event.set_result(None))
+ loop.run_until_complete(event)
+
+ def test_exit_listener_after_exit(self):
+ """
+ Test that callbacks can be registered via the AsynchronousTask
+ addExitListener method even after the task is done, and
+ verify that the callbacks are called.
+ """
+ loop = asyncio._wrap_loop()
+ task = AsynchronousTask(scheduler=loop)
+ loop.run_until_complete(task.async_start())
+ loop.run_until_complete(task.async_wait())
+
+ for i in range(3):
+ event = loop.create_future()
+ task.addExitListener(lambda task: event.set_result(None))
+ loop.run_until_complete(event)