/// <summary> /// NotThreadSafe, this method should only be called from the component host thread /// Called by the build component host when a component is first initialized. /// </summary> /// <param name="buildComponentHost">The component host for this object</param> /// <exception cref="InternalErrorException">When buildComponentHost is null</exception> /// <exception cref="InternalErrorException">Service has already shutdown</exception> public void InitializeComponent(IBuildComponentHost buildComponentHost) { lock (_lockObject) { ErrorUtilities.VerifyThrow(_serviceState != LoggingServiceState.Shutdown, " The object is shutdown, should not do any operations on a shutdown component"); ErrorUtilities.VerifyThrow(buildComponentHost != null, "BuildComponentHost was null"); _componentHost = buildComponentHost; // Get the number of initial nodes the host is running with, if the component host does not have // this information default to 1 _maxCPUCount = buildComponentHost.BuildParameters.MaxNodeCount; // Ask the component host if onlyLogCriticalEvents is true or false. If the host does // not have this information default to false. _onlyLogCriticalEvents = buildComponentHost.BuildParameters.OnlyLogCriticalEvents; _serviceState = LoggingServiceState.Initialized; } }
/// <summary> /// NotThreadSafe, this method should only be called from the component host thread /// Called by the build component host when the component host is about to shutdown. /// 1. Shutdown forwarding loggers so that any events they have left to forward can get into the queue /// 2. Terminate the logging thread /// 3. Null out sinks and the filter event source so that no more events can get to the central loggers /// 4. Shutdown the central loggers /// </summary> /// <exception cref="InternalErrorException">Service has already shutdown</exception> /// <exception cref="LoggerException"> A logger may throw a logger exception when shutting down</exception> /// <exception cref="InternalLoggerException">A logger will wrap other exceptions (except ExceptionHandling.IsCriticalException exceptions) in a InternalLoggerException if it crashes during shutdown</exception> public void ShutdownComponent() { lock (_lockObject) { ErrorUtilities.VerifyThrow(_serviceState != LoggingServiceState.Shutdown, " The object is shutdown, should not do any operations on a shutdown component"); // Set the state to indicate we are starting the shutdown process. _serviceState = LoggingServiceState.ShuttingDown; try { try { // 1. Shutdown forwarding loggers so that any events they have left to forward can get into the queue foreach (ILogger logger in _iloggerList) { if (logger is IForwardingLogger) { ShutdownLogger(logger); } } } finally { // 2. Terminate the logging event queue if (_logMode == LoggerMode.Asynchronous) { TerminateLoggingEventQueue(); } } // 3. Null out sinks and the filter event source so that no more events can get to the central loggers if (_filterEventSource != null) { _filterEventSource.ShutDown(); } foreach (IBuildEventSink sink in _eventSinkDictionary.Values) { sink.ShutDown(); } // 4. Shutdown the central loggers foreach (ILogger logger in _iloggerList) { ShutdownLogger(logger); } } finally { // Revert the centralLogger sinId back to -1 so that when another central logger is registered, it will generate a new // sink for the central loggers. _centralLoggerSinkId = -1; // Clean up anything related to the asynchronous logging if (_logMode == LoggerMode.Asynchronous) { _loggingQueue = null; _loggingQueueProcessor = null; } _iloggerList = new List<ILogger>(); _loggerDescriptions = null; _eventSinkDictionary = null; _filterEventSource = null; _serviceState = LoggingServiceState.Shutdown; } } }
/// <summary> /// Initialize an instance of a loggingService. /// </summary> /// <param name="loggerMode">Should the events be processed synchronously or asynchronously</param> protected LoggingService(LoggerMode loggerMode, int nodeId) { _projectFileMap = new Dictionary<int, string>(); _logMode = loggerMode; _iloggerList = new List<ILogger>(); _loggerDescriptions = new List<LoggerDescription>(); _eventSinkDictionary = new Dictionary<int, IBuildEventSink>(); _nodeId = nodeId; _configCache = new Lazy<IConfigCache>(() => (IConfigCache)_componentHost.GetComponent(BuildComponentType.ConfigCache), LazyThreadSafetyMode.PublicationOnly); // Start the project context id count at the nodeId _nextProjectId = nodeId; string queueCapacityEnvironment = Environment.GetEnvironmentVariable("MSBUILDLOGGINGQUEUECAPACITY"); if (!String.IsNullOrEmpty(queueCapacityEnvironment)) { uint localQueueCapacity; if (UInt32.TryParse(queueCapacityEnvironment, out localQueueCapacity)) { _queueCapacity = localQueueCapacity; } _queueCapacity = Math.Max(0, _queueCapacity); } if (_logMode == LoggerMode.Asynchronous) { CreateLoggingEventQueue(); } _serviceState = LoggingServiceState.Instantiated; }