commit:     f97e414ce980299acc962e357db24106d62e4c7c
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Feb  4 06:12:00 2024 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Feb  4 08:27:37 2024 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=f97e414c

set_term_size: Wait asynchronously if event loop is running

When set_term_size is called from an asynchronous context, we
can wait for the process to exit asynchronously. This will
prevent a "RuntimeError: This event loop is already running"
error in the future when synchronous spawn calls will need
to run the event loop in order to wait for the spawned
process(es).

Bug: https://bugs.gentoo.org/923750
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/output.py | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/portage/output.py b/lib/portage/output.py
index cdeeb18e99..7d3a6278f3 100644
--- a/lib/portage/output.py
+++ b/lib/portage/output.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2021 Gentoo Authors
+# Copyright 1998-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 __docformat__ = "epytext"
@@ -13,7 +13,9 @@ import portage
 
 portage.proxy.lazyimport.lazyimport(
     globals(),
+    "portage.process:spawn",
     "portage.util:writemsg",
+    "portage.util.futures:asyncio",
 )
 import portage.util.formatter as formatter
 
@@ -557,13 +559,20 @@ def set_term_size(lines, columns, fd):
     Set the number of lines and columns for the tty that is connected to fd.
     For portability, this simply calls `stty rows $lines columns $columns`.
     """
-    from portage.process import spawn
 
     cmd = ["stty", "rows", str(lines), "columns", str(columns)]
     try:
-        spawn(cmd, env=os.environ, fd_pipes={0: fd})
+        proc = spawn(cmd, env=os.environ, fd_pipes={0: fd}, returnproc=True)
     except CommandNotFound:
         writemsg(_("portage: stty: command not found\n"), noiselevel=-1)
+    else:
+        loop = asyncio.get_event_loop()
+        if loop.is_running():
+            asyncio.ensure_future(proc.wait(), loop).add_done_callback(
+                lambda future: future.result()
+            )
+        else:
+            loop.run_until_complete(proc.wait())
 
 
 class EOutput:

Reply via email to