From e4e2118f107d1c687bd02abb261f3ae9143fae86 Mon Sep 17 00:00:00 2001 From: Drew Noakes Date: Thu, 13 Jul 2023 11:04:18 +1000 Subject: [PATCH] Avoid bug during FUTDC validation after solution build completes In some cases (such as when FUTDC logging is enabled) we run a validation pass to report to the user when their projects appear out of date despite just having been built. This feature alerts users to overbuild and provides useful diagnostic information to correct it. #9130 fixed a bug related to F5 builds. It introduced a race condition that can lead to the error reported in #9152. Our `CurrentSolutionBuildContext` value is set when the SBM starts the solution build, and cleared to `null` when it completes. Our validation logic runs async, and can complete after the SBM completes. In such cases, it can observe a null `CurrentSolutionBuildContext` value, which is not supported by the current code. This change captures the `CurrentSolutionBuildContext` value early on to ensure it's non-null when we need it later on, and passes the specific value down, preventing any issues from null values. --- .../ProjectSystem/UpToDate/BuildUpToDateCheck.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.cs index 087ad6525d9..0ae0787d632 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.cs @@ -722,11 +722,9 @@ private bool CheckBuiltFromInputFiles(Log log, in TimestampCache timestampCache, return true; } - private bool CheckCopyToOutputDirectoryItems(Log log, UpToDateCheckImplicitConfiguredInput state, IEnumerable<(string Path, ImmutableArray CopyItems)> copyItemsByProject, ConfiguredFileSystemOperationAggregator fileSystemAggregator, bool? isBuildAccelerationEnabled, CancellationToken token) + private bool CheckCopyToOutputDirectoryItems(Log log, UpToDateCheckImplicitConfiguredInput state, IEnumerable<(string Path, ImmutableArray CopyItems)> copyItemsByProject, ConfiguredFileSystemOperationAggregator fileSystemAggregator, bool? isBuildAccelerationEnabled, SolutionBuildContext solutionBuildContext, CancellationToken token) { - ITimestampCache? timestampCache = _solutionBuildContextProvider.CurrentSolutionBuildContext?.CopyItemTimestamps; - - Assumes.NotNull(timestampCache); + ITimestampCache timestampCache = solutionBuildContext.CopyItemTimestamps; string outputFullPath = Path.Combine(state.MSBuildProjectDirectory, state.OutputRelativeOrFullPath); @@ -973,10 +971,12 @@ private async Task IsUpToDateInternalAsync( // // In either case, we construct an event here lazily so that we can correctly test for the // existence of copy items in CheckCopyToOutputDirectoryItems. - if (_solutionBuildContextProvider.CurrentSolutionBuildContext is null) + SolutionBuildContext? solutionBuildContext = _solutionBuildContextProvider.CurrentSolutionBuildContext; + if (solutionBuildContext is null) { _solutionBuildEventListener.NotifySolutionBuildStarting(); - Assumes.NotNull(_solutionBuildContextProvider.CurrentSolutionBuildContext); + solutionBuildContext = _solutionBuildContextProvider.CurrentSolutionBuildContext; + Assumes.NotNull(solutionBuildContext); } globalProperties.TryGetValue(FastUpToDateCheckIgnoresKindsGlobalPropertyName, out string? ignoreKindsString); @@ -1083,7 +1083,7 @@ private async Task IsUpToDateInternalAsync( !CheckInputsAndOutputs(logger, lastSuccessfulBuildStartTimeUtc, timestampCache, implicitState, ignoreKinds, token) || !CheckBuiltFromInputFiles(logger, timestampCache, implicitState, token) || !CheckMarkers(logger, timestampCache, implicitState, isBuildAccelerationEnabled, fileSystemOperations) || - !CheckCopyToOutputDirectoryItems(logger, implicitState, copyInfo.ItemsByProject, configuredFileSystemOperations, isBuildAccelerationEnabled, token)) + !CheckCopyToOutputDirectoryItems(logger, implicitState, copyInfo.ItemsByProject, configuredFileSystemOperations, isBuildAccelerationEnabled, solutionBuildContext, token)) { return (false, checkedConfigurations); }