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

svn path=/main/branches/2.1.2/; revision=8793

bin/emerge

index 6c3bf2b18aed50f950de4c7493e7674986eab109..03dc11dd509f4faf14894691ffcdd48ba1945d2b 100755 (executable)
@@ -3649,8 +3649,37 @@ class MergeTask(object):
                        self.pkgsettings["/"] = \
                                portage.config(clone=trees["/"]["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,
+                               # so remove it from our list.
+                               pass
+                       spawned_pids.remove(pid)
+
+       def _merge(self, mylist, favorites, mtimedb):
                failed_fetches = []
                fetchonly = "--fetchonly" in self.myopts or \
                        "--fetch-all-uri" in self.myopts
@@ -3755,8 +3784,10 @@ class MergeTask(object):
                                                        fetch_args.append(myopt)
                                                else:
                                                        fetch_args.append(myopt +"="+ myarg)
-                               portage.portage_exec.spawn(fetch_args, env=fetch_env,
-                                       fd_pipes=fd_pipes, returnpid=True)
+                               self._spawned_pids.extend(
+                                       portage.portage_exec.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
@@ -4087,6 +4118,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...")