diff --git a/project.py b/project.py index 86e2756d..610dd5a7 100644 --- a/project.py +++ b/project.py @@ -1909,6 +1909,9 @@ class Project(object): # mode, we just tried sync'ing from the upstream field; it doesn't exist, thus # abort the optimization attempt and do a full sync. break + elif ret < 0: + # Git died with a signal, exit immediately + break time.sleep(random.randint(30, 45)) if initial: diff --git a/subcmds/forall.py b/subcmds/forall.py index 88b23fbd..6a6d30c9 100644 --- a/subcmds/forall.py +++ b/subcmds/forall.py @@ -20,6 +20,7 @@ import multiprocessing import re import os import select +import signal import sys import subprocess @@ -207,14 +208,12 @@ without iterating through the remaining projects. os.environ['REPO_COUNT'] = str(len(projects)) - pool = multiprocessing.Pool(opt.jobs) + pool = multiprocessing.Pool(opt.jobs, InitWorker) try: config = self.manifest.manifestProject.config results_it = pool.imap( DoWorkWrapper, - ([mirror, opt, cmd, shell, cnt, config, self._SerializeProject(p)] - for cnt, p in enumerate(projects)) - ) + self.ProjectArgs(projects, mirror, opt, cmd, shell, config)) pool.close() for r in results_it: rc = rc or r @@ -236,12 +235,28 @@ without iterating through the remaining projects. if rc != 0: sys.exit(rc) + def ProjectArgs(self, projects, mirror, opt, cmd, shell, config): + for cnt, p in enumerate(projects): + try: + project = self._SerializeProject(p) + except Exception as e: + print('Project list error: %r' % e, + file=sys.stderr) + return + except KeyboardInterrupt: + print('Project list interrupted', + file=sys.stderr) + return + yield [mirror, opt, cmd, shell, cnt, config, project] class WorkerKeyboardInterrupt(Exception): """ Keyboard interrupt exception for worker processes. """ pass +def InitWorker(): + signal.signal(signal.SIGINT, signal.SIG_IGN) + def DoWorkWrapper(args): """ A wrapper around the DoWork() method.