diff options
author | Zac Medico <zmedico@gentoo.org> | 2008-07-04 03:03:44 +0000 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2008-07-04 03:03:44 +0000 |
commit | 9845d081c30352f7d5246ae79f372373b3b0d76a (patch) | |
tree | e2187cb154747eaf84f12e323f7d7878fc5a0a69 | |
parent | e97b8f08b2ebcded360ea1d9c11420e7d931234b (diff) | |
download | portage-9845d081c30352f7d5246ae79f372373b3b0d76a.tar.gz portage-9845d081c30352f7d5246ae79f372373b3b0d76a.tar.bz2 portage-9845d081c30352f7d5246ae79f372373b3b0d76a.zip |
When logging is disabled, make the EbuildPhase create a dummy pipe to provide
a file descriptor that the scheduler can use to monitor the process from
inside a poll() loop.
svn path=/main/trunk/; revision=10920
-rw-r--r-- | pym/_emerge/__init__.py | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 25cbc3bb5..b02d347bc 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -1881,6 +1881,11 @@ class EbuildPhase(SubProcess): _files_dict = slot_dict_class(_file_names, prefix="") _bufsize = 4096 + # A file descriptor is required for the scheduler to monitor changes from + # inside a poll() loop. When logging is not enabled, create a pipe just to + # serve this purpose alone. + _dummy_pipe_fd = 9 + def start(self): root_config = self.pkg.root_config tree = self.tree @@ -1931,7 +1936,6 @@ class EbuildPhase(SubProcess): mode[1] &= ~termios.OPOST termios.tcsetattr(slave_fd, termios.TCSANOW, mode) - import fcntl fcntl.fcntl(master_fd, fcntl.F_SETFL, fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) @@ -1945,6 +1949,17 @@ class EbuildPhase(SubProcess): fd_pipes[1] = slave_fd fd_pipes[2] = slave_fd + else: + # Create a dummy pipe so the scheduler can monitor + # the process from inside a poll() loop. + master_fd, slave_fd = os.pipe() + fcntl.fcntl(master_fd, fcntl.F_SETFL, + fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) + fd_pipes.setdefault(0, sys.stdin.fileno()) + fd_pipes.setdefault(1, sys.stdout.fileno()) + fd_pipes.setdefault(2, sys.stderr.fileno()) + fd_pipes[self._dummy_pipe_fd] = slave_fd + retval = portage.doebuild(ebuild_path, self.phase, root_config.root, settings, debug, mydbapi=mydbapi, tree=tree, @@ -1953,13 +1968,16 @@ class EbuildPhase(SubProcess): self.pid = retval[0] if logfile: - os.close(slave_fd) files.log = open(logfile, 'a') files.stdout = os.fdopen(os.dup(fd_pipes_orig[1]), 'w') - files.ebuild = os.fdopen(master_fd, 'r') - self.registered = True - self.register(files.ebuild.fileno(), - select.POLLIN, self._output_handler) + output_handler = self._output_handler + else: + output_handler = self._dummy_handler + + os.close(slave_fd) + files.ebuild = os.fdopen(master_fd, 'r') + self.registered = True + self.register(files.ebuild.fileno(), select.POLLIN, output_handler) def _output_handler(self, fd, event): files = self.files @@ -1980,6 +1998,27 @@ class EbuildPhase(SubProcess): self.registered = False self.unregister(fd) + def _dummy_handler(self, fd, event): + """ + This method is mainly interested in detecting EOF, since + the only purpose of the pipe is to allow the scheduler to + monitor the process from inside a poll() loop. + """ + files = self.files + buf = array.array('B') + try: + buf.fromfile(files.ebuild, self._bufsize) + except EOFError: + pass + if buf: + pass + else: + fd = files.ebuild.fileno() + for f in files.values(): + f.close() + self.registered = False + self.unregister(fd) + def _set_returncode(self, wait_retval): SubProcess._set_returncode(self, wait_retval) msg = portage._doebuild_exit_status_check( |