From 9cb900a38fed06178d8c6281c2e9466187666732 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/actions.py | 67 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'pym/_emerge/actions.py') diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 39bfdbfca..2caa4740d 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -420,11 +420,7 @@ def action_build(settings, trees, mtimedb, mergetask = Scheduler(settings, trees, mtimedb, myopts, spinner, favorites=favorites, graph_config=mydepgraph.schedulerGraph()) - del mydepgraph - clear_caches(trees) - retval = mergetask.merge() - merge_count = mergetask.curval else: if "resume" in mtimedb and \ "mergelist" in mtimedb["resume"] and \ @@ -434,14 +430,40 @@ def action_build(settings, trees, mtimedb, mtimedb.commit() mydepgraph.saveNomergeFavorites() - mergetask = Scheduler(settings, trees, mtimedb, myopts, - spinner, favorites=favorites, - graph_config=mydepgraph.schedulerGraph()) - del mydepgraph - clear_caches(trees) + mergetask = Scheduler(settings, trees, mtimedb, myopts, + spinner, favorites=favorites, + graph_config=mydepgraph.schedulerGraph()) + + del mydepgraph + clear_caches(trees) + + received_signal = [] + + def emergeexitsig(signum, frame): + signal.signal(signal.SIGINT, signal.SIG_IGN) + signal.signal(signal.SIGTERM, signal.SIG_IGN) + portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % \ + {"signal":signum}) + mergetask.terminate() + received_signal.append(128 + signum) + + earlier_sigint_handler = signal.signal(signal.SIGINT, emergeexitsig) + earlier_sigterm_handler = signal.signal(signal.SIGTERM, emergeexitsig) + + try: retval = mergetask.merge() - merge_count = mergetask.curval + + if received_signal: + sys.exit(received_signal[0]) + finally: + # Restore previous handlers + if earlier_sigint_handler is not None: + signal.signal(signal.SIGINT, earlier_sigint_handler) + if earlier_sigterm_handler is not None: + signal.signal(signal.SIGTERM, earlier_sigterm_handler) + + merge_count = mergetask.curval if retval == os.EX_OK and not (buildpkgonly or fetchonly or pretend): if "yes" == settings.get("AUTOCLEAN"): @@ -1809,7 +1831,30 @@ def action_regen(settings, portdb, max_jobs, max_load): sys.stdout.flush() regen = MetadataRegen(portdb, max_jobs=max_jobs, max_load=max_load) - regen.run() + received_signal = [] + + def emergeexitsig(signum, frame): + signal.signal(signal.SIGINT, signal.SIG_IGN) + signal.signal(signal.SIGTERM, signal.SIG_IGN) + portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % \ + {"signal":signum}) + regen.terminate() + received_signal.append(128 + signum) + + earlier_sigint_handler = signal.signal(signal.SIGINT, emergeexitsig) + earlier_sigterm_handler = signal.signal(signal.SIGTERM, emergeexitsig) + + try: + regen.run() + + if received_signal: + sys.exit(received_signal[0]) + finally: + # Restore previous handlers + if earlier_sigint_handler is not None: + signal.signal(signal.SIGINT, earlier_sigint_handler) + if earlier_sigterm_handler is not None: + signal.signal(signal.SIGTERM, earlier_sigterm_handler) portage.writemsg_stdout("done!\n") return regen.returncode -- cgit v1.2.3-1-g7c22