BaseTools: Add the support for python 2

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1875

python3 change the module name of Queue to queue.
python3 add a new log handler of QueueHandler.

This patch is to make Multiple process AutoGen
feature work for python2

Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Feng, Bob C 2019-07-30 18:19:33 +08:00
parent c60fb00f6c
commit 4acae2b38e
2 changed files with 92 additions and 5 deletions

View File

@ -16,7 +16,10 @@ import os
from Common.MultipleWorkspace import MultipleWorkspace as mws from Common.MultipleWorkspace import MultipleWorkspace as mws
from AutoGen.AutoGen import AutoGen from AutoGen.AutoGen import AutoGen
from Workspace.WorkspaceDatabase import BuildDB from Workspace.WorkspaceDatabase import BuildDB
from queue import Empty try:
from queue import Empty
except:
from Queue import Empty
import traceback import traceback
import sys import sys
from AutoGen.DataPipe import MemoryDataPipe from AutoGen.DataPipe import MemoryDataPipe

View File

@ -5,12 +5,96 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# This copyright is for QueueHandler.
## Import modules ## Import modules
from __future__ import absolute_import from __future__ import absolute_import
import Common.LongFilePathOs as os, sys, logging import Common.LongFilePathOs as os, sys, logging
import traceback import traceback
from .BuildToolError import * from .BuildToolError import *
import logging.handlers try:
from logging.handlers import QueueHandler
except:
class QueueHandler(logging.Handler):
"""
This handler sends events to a queue. Typically, it would be used together
with a multiprocessing Queue to centralise logging to file in one process
(in a multi-process application), so as to avoid file write contention
between processes.
This code is new in Python 3.2, but this class can be copy pasted into
user code for use with earlier Python versions.
"""
def __init__(self, queue):
"""
Initialise an instance, using the passed queue.
"""
logging.Handler.__init__(self)
self.queue = queue
def enqueue(self, record):
"""
Enqueue a record.
The base implementation uses put_nowait. You may want to override
this method if you want to use blocking, timeouts or custom queue
implementations.
"""
self.queue.put_nowait(record)
def prepare(self, record):
"""
Prepares a record for queuing. The object returned by this method is
enqueued.
The base implementation formats the record to merge the message
and arguments, and removes unpickleable items from the record
in-place.
You might want to override this method if you want to convert
the record to a dict or JSON string, or send a modified copy
of the record while leaving the original intact.
"""
# The format operation gets traceback text into record.exc_text
# (if there's exception data), and also returns the formatted
# message. We can then use this to replace the original
# msg + args, as these might be unpickleable. We also zap the
# exc_info and exc_text attributes, as they are no longer
# needed and, if not None, will typically not be pickleable.
msg = self.format(record)
record.message = msg
record.msg = msg
record.args = None
record.exc_info = None
record.exc_text = None
return record
def emit(self, record):
"""
Emit a record.
Writes the LogRecord to the queue, preparing it for pickling first.
"""
try:
self.enqueue(self.prepare(record))
except Exception:
self.handleError(record)
## Log level constants ## Log level constants
DEBUG_0 = 1 DEBUG_0 = 1
@ -208,19 +292,19 @@ def LogClientInitialize(log_q):
# #
# For DEBUG level (All DEBUG_0~9 are applicable) # For DEBUG level (All DEBUG_0~9 are applicable)
_DebugLogger.setLevel(INFO) _DebugLogger.setLevel(INFO)
_DebugChannel = logging.handlers.QueueHandler(log_q) _DebugChannel = QueueHandler(log_q)
_DebugChannel.setFormatter(_DebugFormatter) _DebugChannel.setFormatter(_DebugFormatter)
_DebugLogger.addHandler(_DebugChannel) _DebugLogger.addHandler(_DebugChannel)
# For VERBOSE, INFO, WARN level # For VERBOSE, INFO, WARN level
_InfoLogger.setLevel(INFO) _InfoLogger.setLevel(INFO)
_InfoChannel = logging.handlers.QueueHandler(log_q) _InfoChannel = QueueHandler(log_q)
_InfoChannel.setFormatter(_InfoFormatter) _InfoChannel.setFormatter(_InfoFormatter)
_InfoLogger.addHandler(_InfoChannel) _InfoLogger.addHandler(_InfoChannel)
# For ERROR level # For ERROR level
_ErrorLogger.setLevel(INFO) _ErrorLogger.setLevel(INFO)
_ErrorCh = logging.handlers.QueueHandler(log_q) _ErrorCh = QueueHandler(log_q)
_ErrorCh.setFormatter(_ErrorFormatter) _ErrorCh.setFormatter(_ErrorFormatter)
_ErrorLogger.addHandler(_ErrorCh) _ErrorLogger.addHandler(_ErrorCh)