After each merge, collect status from child processes
authorZac Medico <zmedico@gentoo.org>
Sat, 1 Dec 2007 21:11:28 +0000 (21:11 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 1 Dec 2007 21:11:28 +0000 (21:11 -0000)
in order to clean up zombies (such as the parallel-fetch
process).

svn path=/main/trunk/; revision=8791

pym/_emerge/__init__.py

index af0ecd323f740d6c8e30c0bb0654e91072c64b77..0abb5760259f538af0d8f03fe8909139f9e3b4de 100644 (file)
@@ -4060,8 +4060,36 @@ class MergeTask(object):
                        self.pkgsettings[root] = portage.config(
                                clone=trees[root]["vartree"].settings)
                self.curval = 0
+               self._spawned_pids = []
 
        def merge(self, mylist, favorites, mtimedb):
+               try:
+                       return self._merge(mylist, favorites, mtimedb)
+               finally:
+                       if self._spawned_pids:
+                               from portage import process
+                               process.spawned_pids.extend(self._spawned_pids)
+                               self._spawned_pids = []
+
+       def _poll_child_processes(self):
+               """
+               After each merge, collect status from child processes
+               in order to clean up zombies (such as the parallel-fetch
+               process).
+               """
+               spawned_pids = self._spawned_pids
+               if not spawned_pids:
+                       return
+               for pid in list(spawned_pids):
+                       try:
+                               if os.waitpid(pid, os.WNOHANG) == (0, 0):
+                                       continue
+                       except OSError:
+                               # This pid has been cleaned up elsewhere.
+                               continue
+                       spawned_pids.remove(pid)
+
+       def _merge(self, mylist, favorites, mtimedb):
                from portage.elog import elog_process
                from portage.elog.filtering import filter_mergephases
                failed_fetches = []
@@ -4168,8 +4196,10 @@ class MergeTask(object):
                                                        fetch_args.append(myopt)
                                                else:
                                                        fetch_args.append(myopt +"="+ myarg)
-                               portage.process.spawn(fetch_args, env=fetch_env,
-                                       fd_pipes=fd_pipes, returnpid=True)
+                               self._spawned_pids.extend(
+                                       portage.process.spawn(
+                                       fetch_args, env=fetch_env,
+                                       fd_pipes=fd_pipes, returnpid=True))
                                logfile.close() # belongs to the spawned process
                                del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
                                        resume_opts
@@ -4504,6 +4534,7 @@ class MergeTask(object):
                        # due to power failure, SIGKILL, etc...
                        mtimedb.commit()
                        self.curval += 1
+                       self._poll_child_processes()
 
                if "--pretend" not in self.myopts:
                        emergelog(xterm_titles, " *** Finished. Cleaning up...")