Skip to content

Commit 433e48e

Browse files
[automated] Merge branch 'vs17.12' => 'main' (#10749)
1 parent fe32fb6 commit 433e48e

35 files changed

+593
-581
lines changed

src/Build.UnitTests/BackEnd/BuildManager_Tests.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,13 +1657,14 @@ public void CancelledBuildWithDelay40()
16571657
string contents = CleanupFileContents(@"
16581658
<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
16591659
<Target Name='test'>
1660-
<Exec Command='" + Helpers.GetSleepCommand(TimeSpan.FromSeconds(10)) + @"'/>
1660+
<Exec Command='" + Helpers.GetSleepCommand(TimeSpan.FromSeconds(20)) + @"'/>
16611661
<Message Text='[errormessage]'/>
16621662
</Target>
16631663
</Project>
16641664
");
16651665
BuildRequestData data = GetBuildRequestData(contents, Array.Empty<string>(), MSBuildDefaultToolsVersion);
16661666
_buildManager.BeginBuild(_parameters);
1667+
Stopwatch sw = Stopwatch.StartNew();
16671668
BuildSubmission asyncResult = _buildManager.PendBuildRequest(data);
16681669
asyncResult.ExecuteAsync(null, null);
16691670

@@ -1675,6 +1676,50 @@ public void CancelledBuildWithDelay40()
16751676

16761677
Assert.Equal(BuildResultCode.Failure, result.OverallResult); // "Build should have failed."
16771678
_logger.AssertLogDoesntContain("[errormessage]");
1679+
// The build should bail out immediately after executing CancelAllSubmissions, build stalling for a longer time
1680+
// is very unexpected.
1681+
sw.Elapsed.ShouldBeLessThan(TimeSpan.FromSeconds(10));
1682+
}
1683+
1684+
/// <summary>
1685+
/// A canceled build which waits for the task to get started before canceling. Because it is a 12.. task, we should
1686+
/// cancel the task and exit out after a short period wherein we wait for the task to exit cleanly.
1687+
///
1688+
/// This test also exercises the possibility of CancelAllSubmissions being executed after EndBuild -
1689+
/// which can happen even if they are synchronously executed in expected order - the CancelAllSubmissions is internally
1690+
/// asynchronous and hence part of the execution can happen after EndBuild.
1691+
/// </summary>
1692+
[Fact]
1693+
public void CancelledBuildWithDelay40_WithThreatSwap()
1694+
{
1695+
string contents = CleanupFileContents(@"
1696+
<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
1697+
<Target Name='test'>
1698+
<Exec Command='" + Helpers.GetSleepCommand(TimeSpan.FromSeconds(20)) + @"'/>
1699+
<Message Text='[errormessage]'/>
1700+
</Target>
1701+
</Project>
1702+
");
1703+
BuildRequestData data = GetBuildRequestData(contents, Array.Empty<string>(), MSBuildDefaultToolsVersion);
1704+
_buildManager.BeginBuild(_parameters);
1705+
Stopwatch sw = Stopwatch.StartNew();
1706+
BuildSubmission asyncResult = _buildManager.PendBuildRequest(data);
1707+
asyncResult.ExecuteAsync(null, null);
1708+
1709+
Thread.Sleep(500);
1710+
// Simulate the case where CancelAllSubmissions is called after EndBuild or its internal queued task is swapped
1711+
// and executed after EndBuild starts execution.
1712+
System.Threading.Tasks.Task.Delay(500).ContinueWith(t => _buildManager.CancelAllSubmissions());
1713+
_buildManager.EndBuild();
1714+
1715+
asyncResult.WaitHandle.WaitOne();
1716+
BuildResult result = asyncResult.BuildResult;
1717+
1718+
Assert.Equal(BuildResultCode.Failure, result.OverallResult); // "Build should have failed."
1719+
_logger.AssertLogDoesntContain("[errormessage]");
1720+
// The build should bail out immediately after executing CancelAllSubmissions, build stalling for a longer time
1721+
// is very unexpected.
1722+
sw.Elapsed.ShouldBeLessThan(TimeSpan.FromSeconds(10));
16781723
}
16791724

16801725
/// <summary>

src/Build/BackEnd/BuildManager/BuildManager.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -789,15 +789,10 @@ void Callback(object? state)
789789
{
790790
lock (_syncLock)
791791
{
792-
if (_shuttingDown)
793-
{
794-
return;
795-
}
796-
797-
// If we are Idle, obviously there is nothing to cancel. If we are waiting for the build to end, then presumably all requests have already completed
798-
// and there is nothing left to cancel. Putting this here eliminates the possibility of us racing with EndBuild to access the nodeManager before
799-
// EndBuild sets it to null.
800-
if (_buildManagerState != BuildManagerState.Building)
792+
// If the state is Idle - then there is yet or already nothing to cancel
793+
// If state is WaitingForBuildToComplete - we might be already waiting gracefully - but CancelAllSubmissions
794+
// is a request for quick abort - so it's fine to resubmit the request
795+
if (_buildManagerState == BuildManagerState.Idle)
801796
{
802797
return;
803798
}
@@ -2078,17 +2073,17 @@ private void ShutdownConnectedNodes(bool abort)
20782073
lock (_syncLock)
20792074
{
20802075
_shuttingDown = true;
2081-
_executionCancellationTokenSource!.Cancel();
2076+
_executionCancellationTokenSource?.Cancel();
20822077

20832078
// If we are aborting, we will NOT reuse the nodes because their state may be compromised by attempts to shut down while the build is in-progress.
2084-
_nodeManager!.ShutdownConnectedNodes(!abort && _buildParameters!.EnableNodeReuse);
2079+
_nodeManager?.ShutdownConnectedNodes(!abort && _buildParameters!.EnableNodeReuse);
20852080

20862081
// if we are aborting, the task host will hear about it in time through the task building infrastructure;
20872082
// so only shut down the task host nodes if we're shutting down tidily (in which case, it is assumed that all
20882083
// tasks are finished building and thus that there's no risk of a race between the two shutdown pathways).
20892084
if (!abort)
20902085
{
2091-
_taskHostNodeManager!.ShutdownConnectedNodes(_buildParameters!.EnableNodeReuse);
2086+
_taskHostNodeManager?.ShutdownConnectedNodes(_buildParameters!.EnableNodeReuse);
20922087
}
20932088
}
20942089
}

src/Build/Resources/xlf/Strings.cs.xlf

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Build/Resources/xlf/Strings.de.xlf

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Build/Resources/xlf/Strings.es.xlf

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)