PageRenderTime 62ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Microsoft.Build/Microsoft.Build/Microsoft/Build/Execution/BuildManager.cs

#
C# | 1029 lines | 976 code | 53 blank | 0 comment | 184 complexity | c1b9151988daebd786038fddc68b68d0 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. namespace Microsoft.Build.Execution
  2. {
  3. using Microsoft.Build;
  4. using Microsoft.Build.BackEnd;
  5. using Microsoft.Build.BackEnd.Logging;
  6. using Microsoft.Build.Evaluation;
  7. using Microsoft.Build.Exceptions;
  8. using Microsoft.Build.Framework;
  9. using Microsoft.Build.Logging;
  10. using Microsoft.Build.Shared;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.IO;
  14. using System.Runtime;
  15. using System.Threading;
  16. public class BuildManager : INodePacketHandler, IBuildComponentHost
  17. {
  18. private bool acquiredProjectRootElementCacheFromProjectInstance;
  19. private HashSet<NGen<int>> activeNodes;
  20. private BuildManagerState buildManagerState;
  21. private BuildParameters buildParameters;
  22. private Dictionary<int, BuildSubmission> buildSubmissions;
  23. private BuildComponentFactoryCollection componentFactories;
  24. private IConfigCache configCache;
  25. private string hostName;
  26. private LegacyThreadingData legacyThreadingData;
  27. private LoggingExceptionDelegate loggingThreadExceptionEventHandler;
  28. private static int nextBuildId;
  29. private int nextBuildRequestConfigurationId;
  30. private int nextBuildSubmissionId;
  31. private int nextUnnamedProjectId;
  32. private AutoResetEvent noActiveSubmissionsEvent;
  33. private NodeConfiguration nodeConfiguration;
  34. private Dictionary<NGen<int>, HashSet<NGen<int>>> nodeIdToKnownConfigurations;
  35. private INodeManager nodeManager;
  36. private AutoResetEvent noNodesActiveEvent;
  37. private bool overallBuildSuccess;
  38. private ProjectFinishedEventHandler projectFinishedEventHandler;
  39. private ProjectStartedEventHandler projectStartedEventHandler;
  40. private Dictionary<int, BuildEventArgs> projectStartedEvents;
  41. private IResultsCache resultsCache;
  42. private IScheduler scheduler;
  43. private bool shuttingDown;
  44. private static BuildManager singletonInstance;
  45. private object syncLock;
  46. private Exception threadException;
  47. private Dictionary<ProjectInstance, string> unnamedProjectInstanceToNames;
  48. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  49. public BuildManager() : this("Unnamed")
  50. {
  51. }
  52. public BuildManager(string hostName)
  53. {
  54. this.syncLock = new object();
  55. ErrorUtilities.VerifyThrowArgumentNull(hostName, "hostName");
  56. this.hostName = hostName;
  57. this.buildManagerState = BuildManagerState.Idle;
  58. this.buildSubmissions = new Dictionary<int, BuildSubmission>();
  59. this.noActiveSubmissionsEvent = new AutoResetEvent(true);
  60. this.activeNodes = new HashSet<NGen<int>>();
  61. this.noNodesActiveEvent = new AutoResetEvent(true);
  62. this.nodeIdToKnownConfigurations = new Dictionary<NGen<int>, HashSet<NGen<int>>>();
  63. this.unnamedProjectInstanceToNames = new Dictionary<ProjectInstance, string>();
  64. this.nextUnnamedProjectId = 1;
  65. this.componentFactories = new BuildComponentFactoryCollection(this);
  66. this.componentFactories.RegisterDefaultFactories();
  67. this.projectStartedEvents = new Dictionary<int, BuildEventArgs>();
  68. this.projectStartedEventHandler = new ProjectStartedEventHandler(this.OnProjectStarted);
  69. this.projectFinishedEventHandler = new ProjectFinishedEventHandler(this.OnProjectFinished);
  70. this.loggingThreadExceptionEventHandler = new LoggingExceptionDelegate(this.OnThreadException);
  71. this.legacyThreadingData = new LegacyThreadingData();
  72. this.nextBuildRequestConfigurationId = 0;
  73. }
  74. public void BeginBuild(BuildParameters parameters)
  75. {
  76. lock (this.syncLock)
  77. {
  78. this.RequireState(BuildManagerState.Idle, "BuildInProgress");
  79. if (Environment.GetEnvironmentVariable("MSBUILDDUMPOPPORTUNISTICINTERNSTATS") == "1")
  80. {
  81. OpportunisticIntern.EnableStatisticsGathering();
  82. }
  83. this.overallBuildSuccess = true;
  84. if (parameters != null)
  85. {
  86. this.buildParameters = parameters.Clone();
  87. }
  88. else
  89. {
  90. this.buildParameters = new BuildParameters();
  91. }
  92. if (this.buildParameters.ResetCaches || ((this.configCache != null) && this.configCache.IsConfigCacheSizeLargerThanThreshold()))
  93. {
  94. this.ResetCaches();
  95. }
  96. this.buildParameters.BuildId = GetNextBuildId();
  97. this.nodeManager = ((IBuildComponentHost) this).GetComponent(BuildComponentType.NodeManager) as INodeManager;
  98. this.scheduler = ((IBuildComponentHost) this).GetComponent(BuildComponentType.Scheduler) as IScheduler;
  99. this.configCache = ((IBuildComponentHost) this).GetComponent(BuildComponentType.ConfigCache) as IConfigCache;
  100. this.resultsCache = ((IBuildComponentHost) this).GetComponent(BuildComponentType.ResultsCache) as IResultsCache;
  101. this.nodeManager.RegisterPacketHandler(NodePacketType.BuildRequestBlocker, new NodePacketFactoryMethod(BuildRequestBlocker.FactoryForDeserialization), this);
  102. this.nodeManager.RegisterPacketHandler(NodePacketType.BuildRequestConfiguration, new NodePacketFactoryMethod(BuildRequestConfiguration.FactoryForDeserialization), this);
  103. this.nodeManager.RegisterPacketHandler(NodePacketType.BuildRequestConfigurationResponse, new NodePacketFactoryMethod(BuildRequestConfigurationResponse.FactoryForDeserialization), this);
  104. this.nodeManager.RegisterPacketHandler(NodePacketType.BuildResult, new NodePacketFactoryMethod(BuildResult.FactoryForDeserialization), this);
  105. this.nodeManager.RegisterPacketHandler(NodePacketType.NodeShutdown, new NodePacketFactoryMethod(NodeShutdown.FactoryForDeserialization), this);
  106. ILoggingService loggingService = this.CreateLoggingService(this.buildParameters.Loggers, this.buildParameters.ForwardingLoggers);
  107. this.componentFactories.ReplaceFactory(BuildComponentType.LoggingService, loggingService as IBuildComponent);
  108. this.nodeManager.RegisterPacketHandler(NodePacketType.LogMessage, new NodePacketFactoryMethod(LogMessagePacket.FactoryForDeserialization), loggingService as INodePacketHandler);
  109. try
  110. {
  111. loggingService.LogBuildStarted();
  112. }
  113. catch (Exception)
  114. {
  115. this.ShutdownLoggingService(loggingService);
  116. throw;
  117. }
  118. if (this.threadException != null)
  119. {
  120. this.ShutdownLoggingService(loggingService);
  121. throw this.threadException;
  122. }
  123. this.buildManagerState = BuildManagerState.Building;
  124. this.noActiveSubmissionsEvent.Set();
  125. this.noNodesActiveEvent.Set();
  126. }
  127. }
  128. public BuildResult Build(BuildParameters parameters, BuildRequestData requestData)
  129. {
  130. BuildResult result;
  131. this.BeginBuild(parameters);
  132. try
  133. {
  134. result = this.BuildRequest(requestData);
  135. if ((result.Exception == null) && (this.threadException != null))
  136. {
  137. result.Exception = this.threadException;
  138. this.threadException = null;
  139. }
  140. }
  141. finally
  142. {
  143. this.EndBuild();
  144. }
  145. return result;
  146. }
  147. public BuildResult BuildRequest(BuildRequestData requestData)
  148. {
  149. return this.PendBuildRequest(requestData).Execute();
  150. }
  151. public void CancelAllSubmissions()
  152. {
  153. ThreadPool.QueueUserWorkItem(delegate (object state) {
  154. lock (this.syncLock)
  155. {
  156. if (!this.shuttingDown && (this.buildManagerState == BuildManagerState.Building))
  157. {
  158. this.overallBuildSuccess = false;
  159. foreach (BuildSubmission submission in this.buildSubmissions.Values)
  160. {
  161. if (submission.BuildRequest != null)
  162. {
  163. BuildResult result = new BuildResult(submission.BuildRequest, new BuildAbortedException());
  164. this.resultsCache.AddResult(result);
  165. submission.CompleteResults(result);
  166. }
  167. }
  168. this.ShutdownNodesAsync(true);
  169. }
  170. }
  171. });
  172. }
  173. private void CheckSubmissionCompletenessAndRemove(BuildSubmission submission)
  174. {
  175. lock (this.syncLock)
  176. {
  177. if (submission.IsCompleted || (submission.BuildRequest == null))
  178. {
  179. this.buildSubmissions.Remove(submission.SubmissionId);
  180. }
  181. if (this.buildSubmissions.Count == 0)
  182. {
  183. this.noActiveSubmissionsEvent.Set();
  184. }
  185. }
  186. }
  187. private ILoggingService CreateLoggingService(IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> forwardingLoggers)
  188. {
  189. LoggerMode mode = ((this.buildParameters.MaxNodeCount == 1) && this.buildParameters.UseSynchronousLogging) ? LoggerMode.Synchronous : LoggerMode.Asynchronous;
  190. ILoggingService loggingService = LoggingService.CreateLoggingService(mode, 1);
  191. ((IBuildComponent) loggingService).InitializeComponent(this);
  192. this.threadException = null;
  193. loggingService.OnLoggingThreadException += this.loggingThreadExceptionEventHandler;
  194. loggingService.OnProjectStarted += this.projectStartedEventHandler;
  195. loggingService.OnProjectFinished += this.projectFinishedEventHandler;
  196. try
  197. {
  198. if (loggers != null)
  199. {
  200. foreach (ILogger logger in loggers)
  201. {
  202. loggingService.RegisterLogger(logger);
  203. }
  204. }
  205. if (loggingService.Loggers.Count == 0)
  206. {
  207. loggingService.RegisterLogger(new NullLogger());
  208. }
  209. if (forwardingLoggers == null)
  210. {
  211. return loggingService;
  212. }
  213. foreach (ForwardingLoggerRecord record in forwardingLoggers)
  214. {
  215. loggingService.RegisterDistributedLogger(record.CentralLogger, record.ForwardingLoggerDescription);
  216. }
  217. }
  218. catch (Exception)
  219. {
  220. if (loggingService != null)
  221. {
  222. this.ShutdownLoggingService(loggingService);
  223. }
  224. throw;
  225. }
  226. return loggingService;
  227. }
  228. public void EndBuild()
  229. {
  230. lock (this.syncLock)
  231. {
  232. this.ErrorIfState(BuildManagerState.WaitingForBuildToComplete, "WaitingForEndOfBuild");
  233. this.ErrorIfState(BuildManagerState.Idle, "NoBuildInProgress");
  234. this.VerifyStateInternal(BuildManagerState.Building);
  235. List<BuildSubmission> list = new List<BuildSubmission>(this.buildSubmissions.Values);
  236. foreach (BuildSubmission submission in list)
  237. {
  238. this.CheckSubmissionCompletenessAndRemove(submission);
  239. }
  240. this.buildManagerState = BuildManagerState.WaitingForBuildToComplete;
  241. }
  242. ILoggingService loggingService = ((IBuildComponentHost) this).LoggingService;
  243. try
  244. {
  245. this.noActiveSubmissionsEvent.WaitOne();
  246. this.ShutdownNodesAsync(false);
  247. this.noNodesActiveEvent.WaitOne();
  248. ErrorUtilities.VerifyThrow(this.buildSubmissions.Count == 0, "All submissions not yet complete.");
  249. ErrorUtilities.VerifyThrow(this.activeNodes.Count == 0, "All nodes not yet shut down.");
  250. if (loggingService != null)
  251. {
  252. loggingService.LogBuildFinished(this.overallBuildSuccess);
  253. }
  254. }
  255. finally
  256. {
  257. this.ShutdownLoggingService(loggingService);
  258. if (this.buildParameters.LegacyThreadingSemantics)
  259. {
  260. this.legacyThreadingData.MainThreadSubmissionId = -1;
  261. }
  262. this.Reset();
  263. this.buildManagerState = BuildManagerState.Idle;
  264. if (this.threadException != null)
  265. {
  266. throw this.threadException;
  267. }
  268. if (Environment.GetEnvironmentVariable("MSBUILDDUMPOPPORTUNISTICINTERNSTATS") == "1")
  269. {
  270. OpportunisticIntern.ReportStatistics();
  271. }
  272. }
  273. }
  274. private void ErrorIfState(BuildManagerState disallowedState, string exceptionResouorce)
  275. {
  276. if (this.buildManagerState == disallowedState)
  277. {
  278. ErrorUtilities.ThrowInvalidOperation(exceptionResouorce, new object[0]);
  279. }
  280. }
  281. internal void ExecuteSubmission(BuildSubmission submission, bool allowMainThreadBuild)
  282. {
  283. ErrorUtilities.VerifyThrowArgumentNull(submission, "submission");
  284. ErrorUtilities.VerifyThrow(!submission.IsCompleted, "Submission already complete.");
  285. ProjectInstance projectInstance = submission.BuildRequestData.ProjectInstance;
  286. if (projectInstance != null)
  287. {
  288. if (this.acquiredProjectRootElementCacheFromProjectInstance)
  289. {
  290. ErrorUtilities.VerifyThrowArgument(this.buildParameters.ProjectRootElementCache == projectInstance.ProjectRootElementCache, "OM_BuildSubmissionsMultipleProjectCollections");
  291. }
  292. else
  293. {
  294. this.buildParameters.ProjectRootElementCache = projectInstance.ProjectRootElementCache;
  295. this.acquiredProjectRootElementCacheFromProjectInstance = true;
  296. }
  297. }
  298. else if (this.buildParameters.ProjectRootElementCache == null)
  299. {
  300. this.buildParameters.ProjectRootElementCache = new ProjectRootElementCache(false);
  301. }
  302. this.VerifyStateInternal(BuildManagerState.Building);
  303. try
  304. {
  305. BuildRequestBlocker blocker;
  306. if (string.IsNullOrEmpty(submission.BuildRequestData.ProjectFullPath))
  307. {
  308. string str;
  309. ErrorUtilities.VerifyThrow(submission.BuildRequestData.ProjectInstance != null, "Unexpected null path for a submission with no ProjectInstance.");
  310. if (!this.unnamedProjectInstanceToNames.TryGetValue(submission.BuildRequestData.ProjectInstance, out str))
  311. {
  312. str = "Unnamed_" + this.nextUnnamedProjectId++;
  313. this.unnamedProjectInstanceToNames[submission.BuildRequestData.ProjectInstance] = str;
  314. }
  315. submission.BuildRequestData.ProjectFullPath = Path.Combine(submission.BuildRequestData.ProjectInstance.GetProperty("MSBuildProjectDirectory").EvaluatedValue, str);
  316. }
  317. BuildRequestConfiguration config = new BuildRequestConfiguration(submission.BuildRequestData, this.buildParameters.DefaultToolsVersion);
  318. BuildRequestConfiguration matchingConfiguration = this.configCache.GetMatchingConfiguration(config);
  319. if (matchingConfiguration != null)
  320. {
  321. lock (this.syncLock)
  322. {
  323. ErrorUtilities.VerifyThrowInvalidOperation(!this.scheduler.IsCurrentlyBuildingConfiguration(matchingConfiguration.ConfigurationId), "ProjectAlreadyBuilding");
  324. foreach (BuildSubmission submission2 in this.buildSubmissions.Values)
  325. {
  326. ErrorUtilities.VerifyThrowInvalidOperation((submission2.BuildRequest == null) || (submission2.BuildRequest.ConfigurationId != matchingConfiguration.ConfigurationId), "ProjectAlreadyBuilding");
  327. }
  328. }
  329. }
  330. BuildRequestConfiguration configuration3 = this.ResolveConfiguration(config, matchingConfiguration, (submission.BuildRequestData.Flags & BuildRequestDataFlags.ReplaceExistingProjectInstance) == BuildRequestDataFlags.ReplaceExistingProjectInstance);
  331. submission.BuildRequest = new Microsoft.Build.BackEnd.BuildRequest(submission.SubmissionId, 0, configuration3.ConfigurationId, submission.BuildRequestData.TargetNames, submission.BuildRequestData.HostServices, BuildEventContext.Invalid, null);
  332. if (this.shuttingDown)
  333. {
  334. BuildResult result = new BuildResult(submission.BuildRequest, new BuildAbortedException());
  335. submission.CompleteResults(result);
  336. submission.CompleteLogging(true);
  337. this.CheckSubmissionCompletenessAndRemove(submission);
  338. }
  339. else
  340. {
  341. blocker = new BuildRequestBlocker(-1, new string[0], new Microsoft.Build.BackEnd.BuildRequest[] { submission.BuildRequest });
  342. ThreadPool.QueueUserWorkItem(delegate (object context) {
  343. try
  344. {
  345. this.IssueRequestToScheduler(submission, allowMainThreadBuild, blocker);
  346. }
  347. catch (Exception exception)
  348. {
  349. this.HandleExecuteSubmissionException(submission, exception);
  350. }
  351. });
  352. }
  353. }
  354. catch (Exception exception)
  355. {
  356. this.HandleExecuteSubmissionException(submission, exception);
  357. throw;
  358. }
  359. }
  360. private I ExpectPacketType<I>(INodePacket packet, NodePacketType expectedType) where I: class, INodePacket
  361. {
  362. I local = packet as I;
  363. ErrorUtilities.VerifyThrow(local != null, "Incorrect packet type: {0} should have been {1}", packet.Type, expectedType);
  364. return local;
  365. }
  366. private int GetNewConfigurationId()
  367. {
  368. if (this.scheduler != null)
  369. {
  370. return (this.scheduler.MinimumAssignableConfigurationId + this.nextBuildRequestConfigurationId++);
  371. }
  372. return ++this.nextBuildRequestConfigurationId;
  373. }
  374. private static int GetNextBuildId()
  375. {
  376. return Interlocked.Increment(ref nextBuildId);
  377. }
  378. private int GetNextSubmissionId()
  379. {
  380. return this.nextBuildSubmissionId++;
  381. }
  382. private NodeConfiguration GetNodeConfiguration()
  383. {
  384. if (this.nodeConfiguration == null)
  385. {
  386. ILoggingService component = ((IBuildComponentHost) this).GetComponent(BuildComponentType.LoggingService) as ILoggingService;
  387. List<LoggerDescription> list = new List<LoggerDescription>(component.LoggerDescriptions);
  388. this.nodeConfiguration = new NodeConfiguration(-1, this.buildParameters, list.ToArray(), AppDomain.CurrentDomain.SetupInformation);
  389. }
  390. return this.nodeConfiguration;
  391. }
  392. public ProjectInstance GetProjectInstanceForBuild(Project project)
  393. {
  394. this.configCache = ((IBuildComponentHost) this).GetComponent(BuildComponentType.ConfigCache) as IConfigCache;
  395. BuildRequestConfiguration matchingConfiguration = this.configCache.GetMatchingConfiguration(new ConfigurationMetadata(project));
  396. if ((matchingConfiguration != null) && matchingConfiguration.IsLoaded)
  397. {
  398. matchingConfiguration.RetrieveFromCache();
  399. return matchingConfiguration.Project;
  400. }
  401. ProjectInstance projectInstance = project.CreateProjectInstance();
  402. matchingConfiguration = new BuildRequestConfiguration(this.GetNewConfigurationId(), new BuildRequestData(projectInstance, new string[0]), null);
  403. this.configCache.AddConfiguration(matchingConfiguration);
  404. return projectInstance;
  405. }
  406. private void HandleConfigurationRequest(int node, BuildRequestConfiguration unresolvedConfiguration)
  407. {
  408. BuildRequestConfiguration configuration = this.ResolveConfiguration(unresolvedConfiguration, null, false);
  409. BuildRequestConfigurationResponse packet = new BuildRequestConfigurationResponse(unresolvedConfiguration.ConfigurationId, configuration.ConfigurationId);
  410. HashSet<NGen<int>> set = null;
  411. if (!this.nodeIdToKnownConfigurations.TryGetValue(node, out set))
  412. {
  413. set = new HashSet<NGen<int>>();
  414. this.nodeIdToKnownConfigurations[node] = set;
  415. }
  416. set.Add(configuration.ConfigurationId);
  417. this.nodeManager.SendData(node, packet);
  418. }
  419. private void HandleExecuteSubmissionException(BuildSubmission submission, Exception ex)
  420. {
  421. InvalidProjectFileException invalidProjectFileException = ex as InvalidProjectFileException;
  422. if ((invalidProjectFileException != null) && !invalidProjectFileException.HasBeenLogged)
  423. {
  424. BuildEventContext buildEventContext = new BuildEventContext(submission.SubmissionId, 1, -1, -2, -1, -1);
  425. ((IBuildComponentHost) this).LoggingService.LogInvalidProjectFileError(buildEventContext, invalidProjectFileException);
  426. invalidProjectFileException.HasBeenLogged = true;
  427. }
  428. if (submission.BuildRequest != null)
  429. {
  430. BuildResult result = new BuildResult(submission.BuildRequest, ex);
  431. submission.CompleteResults(result);
  432. submission.CompleteLogging(true);
  433. }
  434. this.overallBuildSuccess = false;
  435. this.CheckSubmissionCompletenessAndRemove(submission);
  436. }
  437. private void HandleNewRequest(int node, BuildRequestBlocker blocker)
  438. {
  439. if (blocker.BuildRequests != null)
  440. {
  441. foreach (Microsoft.Build.BackEnd.BuildRequest request in blocker.BuildRequests)
  442. {
  443. BuildRequestConfiguration config = this.configCache[request.ConfigurationId];
  444. if (FileUtilities.IsSolutionFilename(config.ProjectFullPath))
  445. {
  446. try
  447. {
  448. this.LoadSolutionIntoConfiguration(config, request.BuildEventContext);
  449. }
  450. catch (InvalidProjectFileException exception)
  451. {
  452. this.resultsCache.AddResult(new BuildResult(request, exception));
  453. if (node == 0)
  454. {
  455. throw;
  456. }
  457. }
  458. }
  459. }
  460. }
  461. IEnumerable<ScheduleResponse> responses = this.scheduler.ReportRequestBlocked(node, blocker);
  462. this.PerformSchedulingActions(responses);
  463. }
  464. private void HandleNodeShutdown(int node, NodeShutdown shutdownPacket)
  465. {
  466. this.shuttingDown = true;
  467. ErrorUtilities.VerifyThrow(this.activeNodes.Contains(node), "Unexpected shutdown from node {0} which shouldn't exist.", node);
  468. this.activeNodes.Remove(node);
  469. if (shutdownPacket.Reason != NodeShutdownReason.Requested)
  470. {
  471. if (shutdownPacket.Reason == NodeShutdownReason.ConnectionFailed)
  472. {
  473. ILoggingService component = ((IBuildComponentHost) this).GetComponent(BuildComponentType.LoggingService) as ILoggingService;
  474. foreach (BuildSubmission submission in this.buildSubmissions.Values)
  475. {
  476. BuildEventContext buildEventContext = new BuildEventContext(submission.SubmissionId, -2, -1, -2, -1, -1);
  477. component.LogError(buildEventContext, new BuildEventFileInfo(string.Empty), "ChildExitedPrematurely", new object[] { node });
  478. }
  479. }
  480. else if (((shutdownPacket.Reason == NodeShutdownReason.Error) && (this.buildSubmissions.Values.Count == 0)) && (shutdownPacket.Exception != null))
  481. {
  482. (((IBuildComponentHost) this).GetComponent(BuildComponentType.LoggingService) as ILoggingService).LogError(BuildEventContext.Invalid, new BuildEventFileInfo(string.Empty), "ChildExitedPrematurely", new object[] { shutdownPacket.Exception.ToString() });
  483. this.OnThreadException(shutdownPacket.Exception);
  484. }
  485. this.nodeManager.ShutdownNodes(this.buildParameters.EnableNodeReuse);
  486. foreach (BuildSubmission submission2 in this.buildSubmissions.Values)
  487. {
  488. if (submission2.BuildRequest != null)
  489. {
  490. this.resultsCache.AddResult(new BuildResult(submission2.BuildRequest, shutdownPacket.Exception ?? new BuildAbortedException()));
  491. }
  492. }
  493. this.scheduler.ReportBuildAborted(node);
  494. }
  495. List<BuildSubmission> list = new List<BuildSubmission>(this.buildSubmissions.Values);
  496. foreach (BuildSubmission submission3 in list)
  497. {
  498. if (submission3.BuildRequest != null)
  499. {
  500. BuildResult resultsForConfiguration = this.resultsCache.GetResultsForConfiguration(submission3.BuildRequest.ConfigurationId);
  501. if (resultsForConfiguration == null)
  502. {
  503. resultsForConfiguration = new BuildResult(submission3.BuildRequest, new BuildAbortedException());
  504. }
  505. submission3.CompleteResults(resultsForConfiguration);
  506. submission3.CompleteLogging(true);
  507. this.overallBuildSuccess = this.overallBuildSuccess && (submission3.BuildResult.OverallResult == BuildResultCode.Success);
  508. this.CheckSubmissionCompletenessAndRemove(submission3);
  509. }
  510. }
  511. if (this.activeNodes.Count == 0)
  512. {
  513. this.noNodesActiveEvent.Set();
  514. }
  515. }
  516. private void HandleResult(int node, BuildResult result)
  517. {
  518. BuildRequestConfiguration configuration = this.configCache[result.ConfigurationId];
  519. if (result.DefaultTargets != null)
  520. {
  521. if (configuration.ProjectDefaultTargets == null)
  522. {
  523. configuration.ProjectDefaultTargets = result.DefaultTargets;
  524. }
  525. if (configuration.ProjectInitialTargets == null)
  526. {
  527. configuration.ProjectInitialTargets = result.InitialTargets;
  528. }
  529. }
  530. IEnumerable<ScheduleResponse> responses = this.scheduler.ReportResult(node, result);
  531. this.PerformSchedulingActions(responses);
  532. }
  533. private void IssueRequestToScheduler(BuildSubmission submission, bool allowMainThreadBuild, BuildRequestBlocker blocker)
  534. {
  535. bool flag = false;
  536. try
  537. {
  538. lock (this.syncLock)
  539. {
  540. if (this.shuttingDown)
  541. {
  542. throw new BuildAbortedException();
  543. }
  544. if ((allowMainThreadBuild && this.buildParameters.LegacyThreadingSemantics) && (this.legacyThreadingData.MainThreadSubmissionId == -1))
  545. {
  546. flag = true;
  547. this.legacyThreadingData.MainThreadSubmissionId = submission.SubmissionId;
  548. }
  549. this.HandleNewRequest(0, blocker);
  550. }
  551. }
  552. catch (Exception exception)
  553. {
  554. InvalidProjectFileException invalidProjectFileException = exception as InvalidProjectFileException;
  555. if (invalidProjectFileException != null)
  556. {
  557. if (!invalidProjectFileException.HasBeenLogged)
  558. {
  559. BuildEventContext buildEventContext = new BuildEventContext(submission.SubmissionId, 1, -1, -2, -1, -1);
  560. ((IBuildComponentHost) this).LoggingService.LogInvalidProjectFileError(buildEventContext, invalidProjectFileException);
  561. invalidProjectFileException.HasBeenLogged = true;
  562. }
  563. }
  564. else if (!(exception is BuildAbortedException) && ExceptionHandling.NotExpectedException(exception))
  565. {
  566. throw;
  567. }
  568. if (flag)
  569. {
  570. this.legacyThreadingData.MainThreadSubmissionId = -1;
  571. }
  572. if (invalidProjectFileException == null)
  573. {
  574. BuildEventContext context2 = new BuildEventContext(submission.SubmissionId, 1, -1, -2, -1, -1);
  575. ((IBuildComponentHost) this).LoggingService.LogFatalBuildError(context2, exception, new BuildEventFileInfo(submission.BuildRequestData.ProjectFullPath));
  576. }
  577. submission.CompleteLogging(true);
  578. this.ReportResultsToSubmission(new BuildResult(submission.BuildRequest, exception));
  579. this.overallBuildSuccess = false;
  580. }
  581. }
  582. internal void LoadSolutionIntoConfiguration(BuildRequestConfiguration config, BuildEventContext buildEventContext)
  583. {
  584. if (!config.IsLoaded)
  585. {
  586. ErrorUtilities.VerifyThrow(FileUtilities.IsSolutionFilename(config.ProjectFullPath), "{0} is not a solution", config.ProjectFullPath);
  587. ProjectInstance[] instanceArray = ProjectInstance.LoadSolutionForBuild(config.ProjectFullPath, config.Properties, config.ExplicitToolsVersionSpecified ? config.ToolsVersion : null, this.buildParameters, ((IBuildComponentHost) this).LoggingService, buildEventContext);
  588. config.Project = instanceArray[0];
  589. for (int i = 1; i < instanceArray.Length; i++)
  590. {
  591. BuildRequestConfiguration configuration = new BuildRequestConfiguration(this.GetNewConfigurationId(), instanceArray[i]);
  592. if (this.configCache.GetMatchingConfiguration(configuration) == null)
  593. {
  594. this.configCache.AddConfiguration(configuration);
  595. }
  596. }
  597. }
  598. }
  599. IBuildComponent IBuildComponentHost.GetComponent(BuildComponentType type)
  600. {
  601. return this.componentFactories.GetComponent(type);
  602. }
  603. void IBuildComponentHost.RegisterFactory(BuildComponentType componentType, BuildComponentFactoryDelegate factory)
  604. {
  605. this.componentFactories.ReplaceFactory(componentType, factory);
  606. }
  607. void INodePacketHandler.PacketReceived(int node, INodePacket packet)
  608. {
  609. lock (this.syncLock)
  610. {
  611. if (!this.shuttingDown || (packet.Type == NodePacketType.NodeShutdown))
  612. {
  613. switch (packet.Type)
  614. {
  615. case NodePacketType.BuildResult:
  616. {
  617. BuildResult result = this.ExpectPacketType<BuildResult>(packet, NodePacketType.BuildResult);
  618. this.HandleResult(node, result);
  619. break;
  620. }
  621. case NodePacketType.NodeShutdown:
  622. {
  623. NodeShutdown shutdownPacket = this.ExpectPacketType<NodeShutdown>(packet, NodePacketType.NodeShutdown);
  624. this.HandleNodeShutdown(node, shutdownPacket);
  625. break;
  626. }
  627. case NodePacketType.BuildRequestConfiguration:
  628. {
  629. BuildRequestConfiguration unresolvedConfiguration = this.ExpectPacketType<BuildRequestConfiguration>(packet, NodePacketType.BuildRequestConfiguration);
  630. this.HandleConfigurationRequest(node, unresolvedConfiguration);
  631. break;
  632. }
  633. case NodePacketType.BuildRequestBlocker:
  634. {
  635. BuildRequestBlocker blocker = this.ExpectPacketType<BuildRequestBlocker>(packet, NodePacketType.BuildRequestBlocker);
  636. this.HandleNewRequest(node, blocker);
  637. break;
  638. }
  639. default:
  640. ErrorUtilities.ThrowInternalError("Unexpected packet received by BuildManager: {0}", new object[] { packet.Type });
  641. break;
  642. }
  643. }
  644. }
  645. }
  646. private void OnProjectFinished(object sender, ProjectFinishedEventArgs e)
  647. {
  648. if (!this.shuttingDown)
  649. {
  650. lock (this.syncLock)
  651. {
  652. BuildEventArgs args;
  653. if (this.projectStartedEvents.TryGetValue(e.BuildEventContext.SubmissionId, out args) && args.BuildEventContext.Equals(e.BuildEventContext))
  654. {
  655. BuildSubmission submission;
  656. this.projectStartedEvents.Remove(e.BuildEventContext.SubmissionId);
  657. if (this.buildSubmissions.TryGetValue(e.BuildEventContext.SubmissionId, out submission))
  658. {
  659. submission.CompleteLogging(false);
  660. this.CheckSubmissionCompletenessAndRemove(submission);
  661. }
  662. }
  663. }
  664. }
  665. }
  666. private void OnProjectStarted(object sender, ProjectStartedEventArgs e)
  667. {
  668. if (!this.projectStartedEvents.ContainsKey(e.BuildEventContext.SubmissionId))
  669. {
  670. this.projectStartedEvents[e.BuildEventContext.SubmissionId] = e;
  671. }
  672. }
  673. private void OnThreadException(Exception e)
  674. {
  675. lock (this.syncLock)
  676. {
  677. if (this.threadException == null)
  678. {
  679. this.threadException = e;
  680. List<BuildSubmission> list = new List<BuildSubmission>(this.buildSubmissions.Values);
  681. foreach (BuildSubmission submission in list)
  682. {
  683. if (submission.BuildRequest == null)
  684. {
  685. continue;
  686. }
  687. submission.CompleteLogging(false);
  688. if ((submission.BuildResult == null) || (submission.BuildResult.Exception == null))
  689. {
  690. if (submission.BuildResult == null)
  691. {
  692. submission.BuildResult = new BuildResult(submission.BuildRequest, e);
  693. }
  694. else
  695. {
  696. submission.BuildResult.Exception = this.threadException;
  697. }
  698. }
  699. this.CheckSubmissionCompletenessAndRemove(submission);
  700. }
  701. }
  702. }
  703. }
  704. public BuildSubmission PendBuildRequest(BuildRequestData requestData)
  705. {
  706. lock (this.syncLock)
  707. {
  708. ErrorUtilities.VerifyThrowArgumentNull(requestData, "requestData");
  709. this.ErrorIfState(BuildManagerState.WaitingForBuildToComplete, "WaitingForEndOfBuild");
  710. this.ErrorIfState(BuildManagerState.Idle, "NoBuildInProgress");
  711. this.VerifyStateInternal(BuildManagerState.Building);
  712. BuildSubmission submission = new BuildSubmission(this, this.GetNextSubmissionId(), requestData, this.buildParameters.LegacyThreadingSemantics);
  713. this.buildSubmissions.Add(submission.SubmissionId, submission);
  714. this.noActiveSubmissionsEvent.Reset();
  715. return submission;
  716. }
  717. }
  718. private void PerformSchedulingActions(IEnumerable<ScheduleResponse> responses)
  719. {
  720. foreach (ScheduleResponse response in responses)
  721. {
  722. List<NodeInfo> list;
  723. int num;
  724. NodeInfo info;
  725. switch (response.Action)
  726. {
  727. case ScheduleActionType.NoAction:
  728. {
  729. continue;
  730. }
  731. case ScheduleActionType.Schedule:
  732. case ScheduleActionType.ScheduleWithConfiguration:
  733. {
  734. if (response.Action == ScheduleActionType.ScheduleWithConfiguration)
  735. {
  736. HashSet<NGen<int>> set = null;
  737. if (!this.nodeIdToKnownConfigurations.TryGetValue(response.NodeId, out set) || !set.Contains(response.BuildRequest.ConfigurationId))
  738. {
  739. IConfigCache component = this.componentFactories.GetComponent(BuildComponentType.ConfigCache) as IConfigCache;
  740. this.nodeManager.SendData(response.NodeId, component[response.BuildRequest.ConfigurationId]);
  741. }
  742. }
  743. this.nodeManager.SendData(response.NodeId, response.BuildRequest);
  744. continue;
  745. }
  746. case ScheduleActionType.ReportResults:
  747. case ScheduleActionType.ResumeExecution:
  748. case ScheduleActionType.CircularDependency:
  749. {
  750. this.nodeManager.SendData(response.NodeId, response.Unblocker);
  751. continue;
  752. }
  753. case ScheduleActionType.CreateNode:
  754. list = new List<NodeInfo>();
  755. num = 0;
  756. goto Label_0107;
  757. case ScheduleActionType.SubmissionComplete:
  758. {
  759. if (this.buildParameters.DetailedSummary)
  760. {
  761. this.scheduler.WriteDetailedSummary(response.BuildResult.SubmissionId);
  762. }
  763. this.ReportResultsToSubmission(response.BuildResult);
  764. continue;
  765. }
  766. default:
  767. goto Label_01B9;
  768. }
  769. Label_00A3:
  770. info = this.nodeManager.CreateNode(this.GetNodeConfiguration(), response.RequiredNodeType);
  771. if (info != null)
  772. {
  773. this.noNodesActiveEvent.Reset();
  774. this.activeNodes.Add(info.NodeId);
  775. list.Add(info);
  776. ErrorUtilities.VerifyThrow(this.activeNodes.Count != 0, "Still 0 nodes after asking for a new node. Build cannot proceed.");
  777. }
  778. num++;
  779. Label_0107:
  780. if (num < response.NumberOfNodesToCreate)
  781. {
  782. goto Label_00A3;
  783. }
  784. IEnumerable<ScheduleResponse> enumerable = this.scheduler.ReportNodesCreated(list);
  785. this.PerformSchedulingActions(enumerable);
  786. continue;
  787. Label_01B9:;
  788. ErrorUtilities.ThrowInternalError("Scheduling action {0} not handled.", new object[] { response.Action });
  789. }
  790. }
  791. private void ReportResultsToSubmission(BuildResult result)
  792. {
  793. lock (this.syncLock)
  794. {
  795. if (this.buildSubmissions.ContainsKey(result.SubmissionId))
  796. {
  797. BuildSubmission submission = this.buildSubmissions[result.SubmissionId];
  798. submission.CompleteResults(result);
  799. if (result.Exception is InternalLoggerException)
  800. {
  801. submission.CompleteLogging(false);
  802. }
  803. this.overallBuildSuccess = this.overallBuildSuccess && (this.buildSubmissions[result.SubmissionId].BuildResult.OverallResult == BuildResultCode.Success);
  804. this.CheckSubmissionCompletenessAndRemove(submission);
  805. }
  806. }
  807. }
  808. private void RequireState(BuildManagerState requiredState, string exceptionResouorce)
  809. {
  810. ErrorUtilities.VerifyThrowInvalidOperation(this.buildManagerState == requiredState, exceptionResouorce);
  811. }
  812. private void Reset()
  813. {
  814. this.nodeManager.UnregisterPacketHandler(NodePacketType.BuildRequestBlocker);
  815. this.nodeManager.UnregisterPacketHandler(NodePacketType.BuildRequestConfiguration);
  816. this.nodeManager.UnregisterPacketHandler(NodePacketType.BuildRequestConfigurationResponse);
  817. this.nodeManager.UnregisterPacketHandler(NodePacketType.BuildResult);
  818. this.nodeManager.UnregisterPacketHandler(NodePacketType.NodeShutdown);
  819. this.nodeManager.ClearPerBuildState();
  820. this.nodeManager = null;
  821. this.shuttingDown = false;
  822. this.nodeConfiguration = null;
  823. this.buildSubmissions.Clear();
  824. this.scheduler.Reset();
  825. this.scheduler = null;
  826. this.acquiredProjectRootElementCacheFromProjectInstance = false;
  827. this.unnamedProjectInstanceToNames.Clear();
  828. this.nodeIdToKnownConfigurations.Clear();
  829. this.nextUnnamedProjectId = 1;
  830. if (this.configCache != null)
  831. {
  832. foreach (BuildRequestConfiguration configuration in this.configCache)
  833. {
  834. configuration.ActivelyBuildingTargets.Clear();
  835. }
  836. }
  837. if (Environment.GetEnvironmentVariable("MSBUILDCLEARXMLCACHEONBUILDMANAGER") == "1")
  838. {
  839. this.buildParameters.ProjectRootElementCache.Clear();
  840. }
  841. }
  842. public void ResetCaches()
  843. {
  844. this.ErrorIfState(BuildManagerState.WaitingForBuildToComplete, "WaitingForEndOfBuild");
  845. this.ErrorIfState(BuildManagerState.Building, "BuildInProgress");
  846. this.configCache = ((IBuildComponentHost) this).GetComponent(BuildComponentType.ConfigCache) as IConfigCache;
  847. this.configCache.ClearConfigurations();
  848. this.resultsCache = ((IBuildComponentHost) this).GetComponent(BuildComponentType.ResultsCache) as IResultsCache;
  849. this.resultsCache.ClearResults();
  850. FileUtilities.ClearCacheDirectory();
  851. }
  852. private BuildRequestConfiguration ResolveConfiguration(BuildRequestConfiguration unresolvedConfiguration, BuildRequestConfiguration matchingConfigurationFromCache, bool replaceProjectInstance)
  853. {
  854. BuildRequestConfiguration config = matchingConfigurationFromCache ?? this.configCache.GetMatchingConfiguration(unresolvedConfiguration);
  855. if (config == null)
  856. {
  857. int configurationIdFromPlan = this.scheduler.GetConfigurationIdFromPlan(unresolvedConfiguration.ProjectFullPath);
  858. if (this.configCache.HasConfiguration(configurationIdFromPlan) || (configurationIdFromPlan == 0))
  859. {
  860. configurationIdFromPlan = this.GetNewConfigurationId();
  861. }
  862. config = unresolvedConfiguration.ShallowCloneWithNewId(configurationIdFromPlan);
  863. this.configCache.AddConfiguration(config);
  864. return config;
  865. }
  866. if (replaceProjectInstance && (unresolvedConfiguration.Project != null))
  867. {
  868. config.Project = unresolvedConfiguration.Project;
  869. this.resultsCache.ClearResultsForConfiguration(config.ConfigurationId);
  870. return config;
  871. }
  872. if (((unresolvedConfiguration.Project != null) && (config.Project != null)) && !object.ReferenceEquals(unresolvedConfiguration.Project, config.Project))
  873. {
  874. this.resultsCache.ClearResultsForConfiguration(config.ConfigurationId);
  875. config.Project = unresolvedConfiguration.Project;
  876. }
  877. return config;
  878. }
  879. private void ShutdownLoggingService(ILoggingService loggingService)
  880. {
  881. if (loggingService != null)
  882. {
  883. loggingService.OnLoggingThreadException -= this.loggingThreadExceptionEventHandler;
  884. loggingService.OnProjectFinished -= this.projectFinishedEventHandler;
  885. loggingService.OnProjectStarted -= this.projectStartedEventHandler;
  886. (loggingService as IBuildComponent).ShutdownComponent();
  887. }
  888. }
  889. private void ShutdownNodesAsync(bool abort)
  890. {
  891. this.shuttingDown = true;
  892. this.nodeManager.ShutdownNodes(!abort && this.buildParameters.EnableNodeReuse);
  893. }
  894. private void VerifyStateInternal(BuildManagerState requiredState)
  895. {
  896. if (this.buildManagerState != requiredState)
  897. {
  898. ErrorUtilities.ThrowInternalError("Expected state {0}, actual state {1}", new object[] { requiredState, this.buildManagerState });
  899. }
  900. }
  901. public static BuildManager DefaultBuildManager
  902. {
  903. get
  904. {
  905. if (singletonInstance == null)
  906. {
  907. singletonInstance = new BuildManager("Default");
  908. }
  909. return singletonInstance;
  910. }
  911. }
  912. BuildParameters IBuildComponentHost.BuildParameters
  913. {
  914. get
  915. {
  916. return this.buildParameters;
  917. }
  918. }
  919. LegacyThreadingData IBuildComponentHost.LegacyThreadingData
  920. {
  921. get
  922. {
  923. return this.legacyThreadingData;
  924. }
  925. }
  926. ILoggingService IBuildComponentHost.LoggingService
  927. {
  928. get
  929. {
  930. return (this.componentFactories.GetComponent(BuildComponentType.LoggingService) as ILoggingService);
  931. }
  932. }
  933. string IBuildComponentHost.Name
  934. {
  935. get
  936. {
  937. return this.hostName;
  938. }
  939. }
  940. private enum BuildManagerState
  941. {
  942. Idle,
  943. Building,
  944. WaitingForBuildToComplete
  945. }
  946. private class NullLogger : ILogger
  947. {
  948. public void Initialize(IEventSource eventSource)
  949. {
  950. }
  951. public void Shutdown()
  952. {
  953. }
  954. public string Parameters
  955. {
  956. get
  957. {
  958. return string.Empty;
  959. }
  960. set
  961. {
  962. }
  963. }
  964. public LoggerVerbosity Verbosity
  965. {
  966. get
  967. {
  968. return LoggerVerbosity.Normal;
  969. }
  970. set
  971. {
  972. }
  973. }

Large files files are truncated, but you can click here to view the full file