From c4451a1e94212025e060cfd8e6a2341527202086 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 15 Jan 2011 16:00:35 -0800 Subject: Add PollScheduler.terminate() for interruption. This allows PollScheduler instances to do basic cleanup and terminate gracefully when SIGINT or SIGTERM signals are received. --- pym/_emerge/MetadataRegen.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'pym/_emerge/MetadataRegen.py') diff --git a/pym/_emerge/MetadataRegen.py b/pym/_emerge/MetadataRegen.py index bb7bb149c..45c4f4d29 100644 --- a/pym/_emerge/MetadataRegen.py +++ b/pym/_emerge/MetadataRegen.py @@ -1,4 +1,4 @@ -# Copyright 1999-2010 Gentoo Foundation +# Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import portage @@ -32,6 +32,11 @@ class MetadataRegen(PollScheduler): self._process_iter = self._iter_metadata_processes() self.returncode = os.EX_OK self._error_count = 0 + self._running_tasks = set() + + def _terminate_tasks(self): + while self._running_tasks: + self._running_tasks.pop().cancel() def _iter_every_cp(self): portage.writemsg_stdout("Listing available packages...\n") @@ -39,7 +44,7 @@ class MetadataRegen(PollScheduler): portage.writemsg_stdout("Regenerating cache entries...\n") every_cp.sort(reverse=True) try: - while True: + while not self._terminated.is_set(): yield every_cp.pop() except IndexError: pass @@ -51,10 +56,14 @@ class MetadataRegen(PollScheduler): consumer = self._consumer for cp in self._cp_iter: + if self._terminated.is_set(): + break cp_set.add(cp) portage.writemsg_stdout("Processing %s\n" % cp) cpv_list = portdb.cp_list(cp) for cpv in cpv_list: + if self._terminated.is_set(): + break valid_pkgs.add(cpv) ebuild_path, repo_path = portdb.findname2(cpv) if ebuild_path is None: @@ -85,6 +94,10 @@ class MetadataRegen(PollScheduler): while self._jobs: self._poll_loop() + if self._terminated.is_set(): + self.returncode = 1 + return + if self._global_cleanse: for mytree in portdb.porttrees: try: @@ -133,12 +146,15 @@ class MetadataRegen(PollScheduler): False otherwise. """ while self._can_add_job(): + if self._terminated.is_set(): + return False try: metadata_process = next(self._process_iter) except StopIteration: return False self._jobs += 1 + self._running_tasks.add(metadata_process) metadata_process.scheduler = self.sched_iface metadata_process.addExitListener(self._metadata_exit) metadata_process.start() @@ -146,12 +162,14 @@ class MetadataRegen(PollScheduler): def _metadata_exit(self, metadata_process): self._jobs -= 1 + self._running_tasks.discard(metadata_process) if metadata_process.returncode != os.EX_OK: self.returncode = 1 self._error_count += 1 self._valid_pkgs.discard(metadata_process.cpv) - portage.writemsg("Error processing %s, continuing...\n" % \ - (metadata_process.cpv,), noiselevel=-1) + if not self._terminated.is_set(): + portage.writemsg("Error processing %s, continuing...\n" % \ + (metadata_process.cpv,), noiselevel=-1) if self._consumer is not None: # On failure, still notify the consumer (in this case the metadata -- cgit v1.2.3-1-g7c22