From: "Brian C. Lane" bcl@redhat.com
With a kickstart it may be possible to run through the status hub without waiting for all the threads to finish. This adds some helper methods to threadMgr and waits for any pending threads before starting the install. --- pyanaconda/install.py | 11 ++++++++++- pyanaconda/threads.py | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 0041778..d98ac72 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -20,13 +20,16 @@ # Red Hat Author(s): Chris Lumens clumens@redhat.com #
-from pyanaconda.constants import ROOT_PATH +from pyanaconda.constants import ROOT_PATH, THREAD_PAYLOAD from blivet import turnOnFilesystems from pyanaconda.bootloader import writeBootLoader from pyanaconda.progress import progress_report, progressQ from pyanaconda.users import createLuserConf, getPassAlgo, Users from pyanaconda import flags from pyanaconda import timezone +from pyanaconda.threads import threadMgr +import logging +log = logging.getLogger("anaconda")
import gettext _ = lambda x: gettext.ldgettext("anaconda", x) @@ -110,6 +113,12 @@ def doInstall(storage, payload, ksdata, instClass): steps += 5 # pre setup phase, packages setup, packages, bootloader, post install progressQ.send_init(steps)
+ # This should be the only thread running, wait for the others to finish if not. + if threadMgr.running > 1: + with progress_report(_("Waiting for %s threads to finish") % (threadMgr.running-1)): + map(log.debug, ("Thread %s is running" % n for n in threadMgr.names)) + threadMgr.wait_all() + with progress_report(_("Setting up the installation environment")): ksdata.addons.setup(storage, ksdata, instClass)
diff --git a/pyanaconda/threads.py b/pyanaconda/threads.py index 0c67279..69da475 100644 --- a/pyanaconda/threads.py +++ b/pyanaconda/threads.py @@ -86,6 +86,15 @@ class ThreadManager(object):
self.raise_error(name)
+ def wait_all(self): + """Wait for all threads to exit and if there was an error re-raise it. + """ + for name in self._objs.keys(): + if self.get(name) == threading.current_thread(): + continue + log.debug("Waiting for thread %s to exit" % name) + self.wait(name) + def set_error(self, name, *exc_info): """Set the error data for a thread
@@ -116,6 +125,24 @@ class ThreadManager(object): cur_thread = threading.current_thread() return cur_thread is self._main_thread
+ @property + def running(self): + """ Return the number of running threads. + + :returns: number of running threads + :rtype: int + """ + return len(self._objs) + + @property + def names(self): + """ Return the names of the running threads. + + :returns: list of thread names + :rtype: list of strings + """ + return self._objs.keys() + class AnacondaThread(threading.Thread): """A threading.Thread subclass that exists only for a couple purposes: