private void NodeLocalEngineLoop() { buildInProgress = true; // Create a logging service for this build request localEngine = new Engine(parentGlobalProperties, toolsetSearchLocations, 1 /* cpus */, true /* child node */, this.nodeId, parentStartupDirectory, null); localEngine.Router.ChildMode = true; localEngine.Router.ParentNode = this; this.outProcLoggingService = new EngineLoggingServicesOutProc(this, localEngine.FlushRequestEvent); if (nodeLoggers.Length != 0) { foreach (LoggerDescription loggerDescription in nodeLoggers) { IForwardingLogger newLogger = null; bool exitedDueToError = true; try { newLogger = loggerDescription.CreateForwardingLogger(); // Check if the class was not found in the assembly if (newLogger == null) { InternalLoggerException.Throw(null, null, "FatalErrorWhileInitializingLogger", true, loggerDescription.Name); } newLogger.Verbosity = loggerDescription.Verbosity; newLogger.Parameters = loggerDescription.LoggerSwitchParameters; newLogger.NodeId = nodeId; EventRedirector newRedirector = new EventRedirector(loggerDescription.LoggerId, outProcLoggingService); newLogger.BuildEventRedirector = newRedirector; exitedDueToError = false; } // Polite logger failure catch (LoggerException e) { ReportUnhandledError(e); } // Logger class was not found catch (InternalLoggerException e) { ReportUnhandledError(e); } catch (Exception e) { // Wrap the exception in a InternalLoggerException and send it to the parent node string errorCode; string helpKeyword; string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "FatalErrorWhileInitializingLogger", loggerDescription.Name); ReportUnhandledError(new InternalLoggerException(message, e, null, errorCode, helpKeyword, true)); } // If there was a failure registering loggers, null out the engine pointer if (exitedDueToError) { localEngine = null; return; } localEngine.RegisterLogger(newLogger); } localEngine.ExternalLoggingServices = outProcLoggingService; } // Hook up logging service to forward all events to the central engine if necessary if (centralizedLogging) { if (nodeLoggers.Length != 0) { localEngine.LoggingServices.ForwardingService = outProcLoggingService; localEngine.ExternalLoggingServices = outProcLoggingService; } else { localEngine.LoggingServices = outProcLoggingService; } } localEngine.LoggingServices.OnlyLogCriticalEvents = this.logOnlyCriticalEvents; if (!useBreadthFirstTraversal) { localEngine.PostEngineCommand(new ChangeTraversalTypeCommand(useBreadthFirstTraversal, true)); } // Post all the requests that passed in while the engine was being constructed // into the engine queue lock (buildRequests) { while (buildRequests.Count != 0) { BuildRequest buildRequest = buildRequests.Dequeue(); localEngine.PostBuildRequest(buildRequest); } } try { // If there are forwarding loggers registered - generate a custom build started if (nodeLoggers.Length > 0) { localEngine.LoggingServices.LogBuildStarted(EngineLoggingServicesInProc.CENTRAL_ENGINE_EVENTSOURCE); localEngine.LoggingServices.ProcessPostedLoggingEvents(); } // Trigger the actual build if shutdown was not called while the engine was being initialized if (!nodeShutdown) { localEngine.EngineBuildLoop(null); } } catch (Exception e) { // Unhandled exception during execution. The node has to be shutdown. ReportUnhandledError(e); } finally { if (localEngine != null) { // Flush all the messages associated before shutting down localEngine.LoggingServices.ProcessPostedLoggingEvents(); NodeManager nodeManager = localEngine.NodeManager; // If the local engine is already shutting down, the TEM will be nulled out if (nodeManager.TaskExecutionModule != null && nodeManager.TaskExecutionModule.TaskExecutionTime != 0) { TimeSpan taskTimeSpan = new TimeSpan(localEngine.NodeManager.TaskExecutionModule.TaskExecutionTime); totalTaskTime = (int)taskTimeSpan.TotalMilliseconds; } localEngine.Shutdown(); } // Flush all the events to the parent engine outProcLoggingService.ProcessPostedLoggingEvents(); // Indicate that the node logger thread should exit exitNodeEvent.Set(); } }