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:
John W. Parent 2022-04-26 15:56:13 -04:00 committed by GitHub
parent 0f4b228eff
commit 83b91246b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 26 deletions

View File

@ -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
while True:
is_killed = _kill.wait(.1)
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()
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()
if is_killed:
break
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,

View File

@ -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,14 +605,9 @@ 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)
with log_output(out):
self.returncode = _invoke_command(
self.command, self.parser, args, unknown)
except SystemExit as e:
self.returncode = e.code