diff options
author | Simon Glass <sjg@chromium.org> | 2021-04-01 13:07:58 +1300 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-01 20:12:10 +0000 |
commit | 6c7bcced3a5b5e752ce8f85ce23648e178b72d5d (patch) | |
tree | 2db1626ddc702bd5ab1458f4cd58a2e3ffdd029d | |
parent | 3e19dc1f0cb2c665bb184946cdd8781aa59d244f (diff) | |
download | chrome-ec-6c7bcced3a5b5e752ce8f85ce23648e178b72d5d.tar.gz |
zmake: Refactor _logging_map to use a class
At present this uses a tuple but it would probably be better to use a
named tuple so the fields are named. But we also want to be able to
track the output (in a future CL), so change it to a class. Use a
log_line() method to avoid anything needing access to its internals.
Also put brackets after the log_output() function so it is easier to
see that it is a function.
BUG=b:177096315
BRANCH=none
TEST=FEATURE=test sudo -E emerge zephyr-build-tools
Signed-off-by: Simon Glass <sjg@chromium.org>
Change-Id: Icca863ee706b368109d24782a994a0a009316650
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2796848
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
-rw-r--r-- | zephyr/zmake/zmake/multiproc.py | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/zephyr/zmake/zmake/multiproc.py b/zephyr/zmake/zmake/multiproc.py index a1ce853796..45bf592c2c 100644 --- a/zephyr/zmake/zmake/multiproc.py +++ b/zephyr/zmake/zmake/multiproc.py @@ -19,10 +19,47 @@ on the screen. _logging_interrupt_pipe = os.pipe() # A condition variable used to synchronize logging operations. _logging_cv = threading.Condition() -# A map of file descriptors to their logger/logging level tuple. +# A map of file descriptors to their LogWriter _logging_map = {} +class LogWriter: + """Contains information about a file descriptor that is producing output + + There is typically one of these for each file descriptor that a process is + writing to while running (stdout and stderr). + + Properties: + _logger: The logger object to use. + _log_level: The logging level to use. + _override_func: A function used to override the log level. The + function will be called once per line prior to logging and will be + passed the arguments of the line and the default log level. + """ + def __init__(self, logger, log_level, log_level_override_func): + self._logger = logger + self._log_level = log_level + self._override_func = log_level_override_func + + def log_line(self, line): + """Log a line of output + + If the log-level override function requests a change in log level, that + causes self._log_level to be updated accordingly. + + Args: + line: Text line to log + """ + if self._override_func: + # Get the new log level and update the default. The reason we + # want to update the default is that if we hit an error, all + # future logging should be moved to the new logging level. This + # greatly simplifies the logic that is needed to update the log + # level. + self._log_level = self._override_func(line, self._log_level) + self._logger.log(self._log_level, line) + + def _log_fd(fd): """Log information from a single file descriptor. @@ -34,7 +71,7 @@ def _log_fd(fd): removed from the map as it is no longer valid. """ with _logging_cv: - logger, log_level, log_level_override_func = _logging_map[fd] + writer = _logging_map[fd] if fd.closed: del _logging_map[fd] _logging_cv.notify_all() @@ -47,15 +84,7 @@ def _log_fd(fd): return line = line.strip() if line: - if log_level_override_func: - # Get the new log level and update the default. The reason we - # want to update the default is that if we hit an error, all - # future logging should be moved to the new logging level. This - # greatly simplifies the logic that is needed to update the log - # level. - log_level = log_level_override_func(line, log_level) - _logging_map[fd] = (logger, log_level, log_level_override_func) - logger.log(log_level, line) + writer.log_line(line) def _prune_logging_fds(): @@ -76,8 +105,8 @@ def _logging_loop(): """The primary logging thread loop. This is the entry point of the logging thread. It will listen for (1) any - new data on the output file descriptors that were added via log_output and - (2) any new file descriptors being added by log_output. Once a file + new data on the output file descriptors that were added via log_output() and + (2) any new file descriptors being added by log_output(). Once a file descriptor is ready to be read, this function will call _log_fd to perform the actual read and logging. """ @@ -93,7 +122,7 @@ def _logging_loop(): _prune_logging_fds() continue if _logging_interrupt_pipe[0] in fds: - # We got a dummy byte sent by log_output, this is a signal used to + # We got a dummy byte sent by log_output(), this is a signal used to # break out of the blocking select.select call to tell us that the # file descriptor set has changed. We just need to read the byte and # remove this descriptor from the list. If we actually have data @@ -122,8 +151,8 @@ def log_output(logger, log_level, file_descriptor, with _logging_cv: if not _logging_thread.is_alive(): _logging_thread.start() - _logging_map[file_descriptor] = (logger, log_level, - log_level_override_func) + _logging_map[file_descriptor] = LogWriter(logger, log_level, + log_level_override_func) # Write a dummy byte to the pipe to break the select so we can add the # new fd. os.write(_logging_interrupt_pipe[1], b'x') |