summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-12-25 01:21:17 +0000
committerZac Medico <zmedico@gentoo.org>2008-12-25 01:21:17 +0000
commit26da1ffb71799b9222fd2dde143d34fc389d5b5b (patch)
treec812e47b6efef1e0dd8fc30e0da1afe14189bbb9
parent1393a06e68c54cb53244f6f918660b42a8567b6b (diff)
downloadportage-26da1ffb71799b9222fd2dde143d34fc389d5b5b.tar.gz
portage-26da1ffb71799b9222fd2dde143d34fc389d5b5b.tar.bz2
portage-26da1ffb71799b9222fd2dde143d34fc389d5b5b.zip
Register for poll events before forking, in order to avoid 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>. (trunk r12285) svn path=/main/branches/2.1.6/; revision=12316
-rw-r--r--pym/_emerge/__init__.py25
1 files changed, 12 insertions, 13 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index c596adc22..c82bd2062 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -2156,6 +2156,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)
@@ -2164,8 +2168,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
@@ -2173,10 +2176,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
@@ -2821,6 +2820,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",
@@ -2830,7 +2835,7 @@ class EbuildMetadataPhase(SubProcess):
if isinstance(retval, int):
# doebuild failed before spawning
- os.close(master_fd)
+ self._unregister()
self.returncode = retval
self.wait()
return
@@ -2838,12 +2843,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())