Merged from trunk -r12282:12285
authorFabian Groffen <grobian@gentoo.org>
Tue, 23 Dec 2008 19:01:45 +0000 (19:01 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 23 Dec 2008 19:01:45 +0000 (19:01 -0000)
   | 12285   | Register for poll events before forking, in order to avoid   |
   | zmedico | potential race conditions in SpawnProcess._start() and       |
   |         | EbuildMetadataPhase._start(). Hopefully this solves hung     |
   |         | poll calls with defunct ebuild.sh processes, reported on     |
   |         | solaris systems by Fabian Groffen <grobian@g.o>.             |

svn path=/main/branches/prefix/; revision=12286

pym/_emerge/__init__.py

index ad4f9342b6e372c48ae2b4ff2e89c1590cfe0fbf..e5f6acd73c3873ca317738c709a264dd7387e72c 100644 (file)
@@ -2202,6 +2202,10 @@ class SpawnProcess(SubProcess):
                kwargs["returnpid"] = True
                kwargs.pop("logfile", None)
 
+               self._reg_id = self.scheduler.register(files.process.fileno(),
+                       PollConstants.POLLIN, output_handler)
+               self._registered = True
+
                retval = self._spawn(self.args, **kwargs)
 
                os.close(slave_fd)
@@ -2210,8 +2214,7 @@ class SpawnProcess(SubProcess):
 
                if isinstance(retval, int):
                        # spawn failed
-                       for f in files.values():
-                               f.close()
+                       self._unregister()
                        self.returncode = retval
                        self.wait()
                        return
@@ -2219,10 +2222,6 @@ class SpawnProcess(SubProcess):
                self.pid = retval[0]
                portage.process.spawned_pids.remove(self.pid)
 
-               self._reg_id = self.scheduler.register(files.process.fileno(),
-                       PollConstants.POLLIN, output_handler)
-               self._registered = True
-
        def _pipe(self, fd_pipes):
                """
                @type fd_pipes: dict
@@ -2867,6 +2866,12 @@ class EbuildMetadataPhase(SubProcess):
 
                fd_pipes[self._metadata_fd] = slave_fd
 
+               self._raw_metadata = []
+               files.ebuild = os.fdopen(master_fd, 'r')
+               self._reg_id = self.scheduler.register(files.ebuild.fileno(),
+                       PollConstants.POLLIN, self._output_handler)
+               self._registered = True
+
                retval = portage.doebuild(ebuild_path, "depend",
                        settings["ROOT"], settings, debug,
                        mydbapi=self.portdb, tree="porttree",
@@ -2876,7 +2881,7 @@ class EbuildMetadataPhase(SubProcess):
 
                if isinstance(retval, int):
                        # doebuild failed before spawning
-                       os.close(master_fd)
+                       self._unregister()
                        self.returncode = retval
                        self.wait()
                        return
@@ -2884,12 +2889,6 @@ class EbuildMetadataPhase(SubProcess):
                self.pid = retval[0]
                portage.process.spawned_pids.remove(self.pid)
 
-               self._raw_metadata = []
-               files.ebuild = os.fdopen(master_fd, 'r')
-               self._reg_id = self.scheduler.register(files.ebuild.fileno(),
-                       PollConstants.POLLIN, self._output_handler)
-               self._registered = True
-
        def _output_handler(self, fd, event):
                files = self._files
                self._raw_metadata.append(files.ebuild.read())