Windows: fix termination of process output redirection (#29923)
The parent thread in the process stdout redirection logic on Windows was closing a file that was being read in child thread, which lead to error-based termination of the reader thread. This updates the interaction to avoid the error.
This commit is contained in:
		@@ -809,19 +809,23 @@ def __enter__(self):
 | 
			
		||||
            def background_reader(reader, echo_writer, _kill):
 | 
			
		||||
                # for each line printed to logfile, read it
 | 
			
		||||
                # if echo: write line to user
 | 
			
		||||
                try:
 | 
			
		||||
                    while True:
 | 
			
		||||
                        is_killed = _kill.wait(.1)
 | 
			
		||||
                        # Flush buffered build output to file
 | 
			
		||||
                        # stdout/err fds refer to log file
 | 
			
		||||
                        self.stderr.flush()
 | 
			
		||||
                        self.stdout.flush()
 | 
			
		||||
 | 
			
		||||
                        line = reader.readline()
 | 
			
		||||
                    while line:
 | 
			
		||||
                        if self.echo:
 | 
			
		||||
                            self.echo_writer.write('{0}'.format(line.decode()))
 | 
			
		||||
                            self.echo_writer.flush()
 | 
			
		||||
                        line = reader.readline()
 | 
			
		||||
                        if self.echo and line:
 | 
			
		||||
                            echo_writer.write('{0}'.format(line.decode()))
 | 
			
		||||
                            echo_writer.flush()
 | 
			
		||||
 | 
			
		||||
                        if is_killed:
 | 
			
		||||
                            break
 | 
			
		||||
                finally:
 | 
			
		||||
                    reader.close()
 | 
			
		||||
 | 
			
		||||
            self._active = True
 | 
			
		||||
            with replace_environment(self.env):
 | 
			
		||||
@@ -837,7 +841,6 @@ def __exit__(self, exc_type, exc_val, exc_tb):
 | 
			
		||||
            self._ioflag = False
 | 
			
		||||
        else:
 | 
			
		||||
            self.writer.close()
 | 
			
		||||
            self.reader.close()
 | 
			
		||||
            self.echo_writer.flush()
 | 
			
		||||
            self.stdout.flush()
 | 
			
		||||
            self.stderr.flush()
 | 
			
		||||
@@ -853,10 +856,7 @@ def force_echo(self):
 | 
			
		||||
        if not self._active:
 | 
			
		||||
            raise RuntimeError(
 | 
			
		||||
                "Can't call force_echo() outside log_output region!")
 | 
			
		||||
        try:
 | 
			
		||||
            yield self
 | 
			
		||||
        finally:
 | 
			
		||||
            pass
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _writer_daemon(stdin_multiprocess_fd, read_multiprocess_fd, write_fd, echo,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
import llnl.util.tty as tty
 | 
			
		||||
import llnl.util.tty.colify
 | 
			
		||||
import llnl.util.tty.color as color
 | 
			
		||||
from llnl.util.tty.log import log_output, winlog
 | 
			
		||||
from llnl.util.tty.log import log_output
 | 
			
		||||
 | 
			
		||||
import spack
 | 
			
		||||
import spack.cmd
 | 
			
		||||
@@ -605,11 +605,6 @@ def __call__(self, *argv, **kwargs):
 | 
			
		||||
 | 
			
		||||
        out = StringIO()
 | 
			
		||||
        try:
 | 
			
		||||
            if sys.platform == 'win32':
 | 
			
		||||
                with winlog(out):
 | 
			
		||||
                    self.returncode = _invoke_command(
 | 
			
		||||
                        self.command, self.parser, args, unknown)
 | 
			
		||||
            else:
 | 
			
		||||
            with log_output(out):
 | 
			
		||||
                self.returncode = _invoke_command(
 | 
			
		||||
                    self.command, self.parser, args, unknown)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user