diff --git a/.vsts-pipelines/templates/build-steps.yml b/.vsts-pipelines/templates/build-steps.yml
index 949093b338..2ebd7b36d1 100644
--- a/.vsts-pipelines/templates/build-steps.yml
+++ b/.vsts-pipelines/templates/build-steps.yml
@@ -5,6 +5,14 @@ phases:
beforeBuild:
- powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; Restart-Service w3svc"
displayName: Prepare repo
+ afterBuild:
+ - task: PublishBuildArtifacts@1
+ displayName: Upload binlog
+ condition: always()
+ inputs:
+ artifactName: logs
+ artifactType: Container
+ pathtoPublish: artifacts/logs/
- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools
parameters:
diff --git a/build/repo.targets b/build/repo.targets
index 5a2620ec75..4415123011 100644
--- a/build/repo.targets
+++ b/build/repo.targets
@@ -92,7 +92,7 @@
-
+
diff --git a/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec b/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec
index 80d9490328..f05fcbbdd8 100644
--- a/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec
+++ b/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec
@@ -25,7 +25,7 @@
-
+
diff --git a/samples/NativeIISSample/NativeIISSample.csproj b/samples/NativeIISSample/NativeIISSample.csproj
index d3c6d51b75..c1f4b88c89 100644
--- a/samples/NativeIISSample/NativeIISSample.csproj
+++ b/samples/NativeIISSample/NativeIISSample.csproj
@@ -4,6 +4,7 @@
netcoreapp2.2
+ true
diff --git a/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj b/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj
index e1c11dddb6..169c79e503 100644
--- a/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj
+++ b/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj
@@ -213,14 +213,6 @@
-
-
- PreserveNewest
-
-
-
-
-
diff --git a/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_schema.xml b/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_schema.xml
deleted file mode 100644
index c1590816b7..0000000000
--- a/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_schema.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp b/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
index 9de2901be5..be4d124437 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
+++ b/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
@@ -44,24 +44,40 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
// key in the applicationInfoHash.
pszApplicationId = pApplication.GetApplicationId();
- // When accessing the m_pApplicationInfoHash, we need to acquire the application manager
- // lock to avoid races on setting state.
- SRWSharedLock lock(m_srwLock);
- if (!m_fDebugInitialize)
{
- DebugInitializeFromConfig(m_pHttpServer, pApplication);
- m_fDebugInitialize = TRUE;
- }
+ // When accessing the m_pApplicationInfoHash, we need to acquire the application manager
+ // lock to avoid races on setting state.
+ SRWSharedLock readLock(m_srwLock);
+ if (!m_fDebugInitialize)
+ {
+ DebugInitializeFromConfig(m_pHttpServer, pApplication);
+ m_fDebugInitialize = TRUE;
+ }
- if (g_fInShutdown)
- {
- FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
- }
+ if (g_fInShutdown)
+ {
+ FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
+ }
- m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
+ m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
+
+ // It's important to release read lock here so exclusive lock
+ // can be reacquired later as SRW lock doesn't allow upgrades
+ }
if (*ppApplicationInfo == NULL)
{
+ // Take exclusive lock before creating the application
+ SRWExclusiveLock writeLock(m_srwLock);
+
+ // Check if other thread created the application
+
+ m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
+ if (*ppApplicationInfo != NULL)
+ {
+ FINISHED(S_OK);
+ }
+
pApplicationInfo = new APPLICATION_INFO(m_pHttpServer);
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pApplication));
@@ -187,7 +203,7 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
DWORD dwPreviousCounter = 0;
APPLICATION_INFO_HASH* table = NULL;
CONFIG_CHANGE_CONTEXT context;
-
+
if (g_fInShutdown)
{
// We are already shutting down, ignore this event as a global configuration change event
diff --git a/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp b/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp
index b2c6b69871..7cb185b0c3 100644
--- a/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp
+++ b/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp
@@ -6,7 +6,7 @@
#include "GlobalVersionUtility.h"
-namespace fs = std::experimental::filesystem;
+namespace fs = std::filesystem;
// throws runtime error if no request handler versions are installed.
// Throw invalid_argument if any argument is null
diff --git a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp
index 1468c7ee37..2e552679e0 100644
--- a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp
+++ b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp
@@ -38,7 +38,7 @@ PollingAppOfflineApplication::AppOfflineExists()
}
-std::experimental::filesystem::path PollingAppOfflineApplication::GetAppOfflineLocation(IHttpApplication& pApplication)
+std::filesystem::path PollingAppOfflineApplication::GetAppOfflineLocation(IHttpApplication& pApplication)
{
- return std::experimental::filesystem::path(pApplication.GetApplicationPhysicalPath()) / "app_offline.htm";
+ return std::filesystem::path(pApplication.GetApplicationPhysicalPath()) / "app_offline.htm";
}
diff --git a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h
index 48e71f6641..516e72b79f 100644
--- a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h
+++ b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h
@@ -30,8 +30,8 @@ public:
void Stop(bool fServerInitiated) override { UNREFERENCED_PARAMETER(fServerInitiated); }
protected:
- std::experimental::filesystem::path m_appOfflineLocation;
- static std::experimental::filesystem::path GetAppOfflineLocation(IHttpApplication& pApplication);
+ std::filesystem::path m_appOfflineLocation;
+ static std::filesystem::path GetAppOfflineLocation(IHttpApplication& pApplication);
private:
static const int c_appOfflineRefreshIntervalMS = 200;
diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp b/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp
index ab827460bf..57644819be 100644
--- a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp
+++ b/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp
@@ -13,7 +13,7 @@
#include "HandleWrapper.h"
#include "Environment.h"
-namespace fs = std::experimental::filesystem;
+namespace fs = std::filesystem;
//
// Runs a standalone appliction.
@@ -98,7 +98,7 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
}
BOOL
-HOSTFXR_UTILITY::IsDotnetExecutable(const std::experimental::filesystem::path & dotnetPath)
+HOSTFXR_UTILITY::IsDotnetExecutable(const std::filesystem::path & dotnetPath)
{
auto name = dotnetPath.filename();
name.replace_extension("");
diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h b/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h
index 1315865803..9e56fb4e28 100644
--- a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h
+++ b/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h
@@ -44,7 +44,7 @@ public:
static
BOOL
IsDotnetExecutable(
- _In_ const std::experimental::filesystem::path & dotnetPath
+ _In_ const std::filesystem::path & dotnetPath
);
static
@@ -74,25 +74,25 @@ public:
);
static
- std::optional
+ std::optional
GetAbsolutePathToHostFxr(
- _In_ const std::experimental::filesystem::path & dotnetPath,
+ _In_ const std::filesystem::path & dotnetPath,
_In_ HANDLE hEventLog
);
static
- std::optional
+ std::optional
GetAbsolutePathToDotnetFromProgramFiles();
static
- std::optional
+ std::optional
InvokeWhereToFindDotnet();
static
- std::optional
+ std::optional
GetAbsolutePathToDotnet(
- _In_ const std::experimental::filesystem::path & applicationPath,
- _In_ const std::experimental::filesystem::path & requestedPath
+ _In_ const std::filesystem::path & applicationPath,
+ _In_ const std::filesystem::path & requestedPath
);
};
diff --git a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
index 6025b459fb..0580c14e85 100644
--- a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
+++ b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
@@ -34,9 +34,7 @@
-
+
diff --git a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
index 85d3751b69..a25bbf3b4f 100644
--- a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
+++ b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
@@ -7,7 +7,7 @@
- V2
+ AspNetCoreModuleV2
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets
index 67c6152880..a5f7fc6088 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets
@@ -1,7 +1,7 @@
- V2
+ AspNetCoreModuleV2
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
index 4a3caadd8e..81cebf1568 100644
--- a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
@@ -20,6 +20,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
internal class IISApplication
{
internal const int ERROR_OBJECT_NOT_FOUND = unchecked((int)0x800710D8);
+ internal const int ERROR_SHARING_VIOLATION = unchecked((int)0x80070020);
private static readonly TimeSpan _timeout = TimeSpan.FromSeconds(10);
private static readonly TimeSpan _retryDelay = TimeSpan.FromMilliseconds(200);
@@ -109,7 +110,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
_logger.LogInformation($"Tried to start site, state: {state.ToString()}");
}
}
- catch (Exception ex) when (ex is DllNotFoundException || (ex is COMException && ex.HResult == ERROR_OBJECT_NOT_FOUND) )
+ catch (Exception ex) when (
+ ex is DllNotFoundException ||
+ ex is COMException &&
+ (ex.HResult == ERROR_OBJECT_NOT_FOUND || ex.HResult == ERROR_SHARING_VIOLATION))
{
// Accessing the site.State property while the site
// is starting up returns the COMException
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj
index 766b470a50..c13eb6214b 100644
--- a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj
@@ -27,10 +27,6 @@
PackageCopyToOutput="true"
PackagePath="contentFiles/any/any/%(ShimComponents.Platform)/%(ShimComponents.PackageSubPath)"/>
-
-
diff --git a/test/Common.FunctionalTests/AppOfflineTests.cs b/test/Common.FunctionalTests/AppOfflineTests.cs
index d8d0861d3a..c191eea4c7 100644
--- a/test/Common.FunctionalTests/AppOfflineTests.cs
+++ b/test/Common.FunctionalTests/AppOfflineTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.IO;
using System.Net;
using System.Net.Http;
@@ -19,6 +20,8 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
[Collection(PublishedSitesCollection.Name)]
public class AppOfflineTests : IISFunctionalTestBase
{
+ private static readonly TimeSpan RetryDelay = TimeSpan.FromMilliseconds(100);
+
private readonly PublishedSitesFixture _fixture;
public AppOfflineTests(PublishedSitesFixture fixture)
@@ -94,7 +97,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
// 1. ANCM detects app_offline before it starts the request - if AssertAppOffline succeeds we've hit it
// 2. Intended scenario where app starts and then shuts down
// In first case we remove app_offline and try again
- await Task.Delay(100);
+ await Task.Delay(RetryDelay);
AddAppOffline(deploymentResult.ContentRoot);
@@ -182,7 +185,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
() => AddAppOffline(deploymentResult.ContentRoot),
e => Logger.LogError($"Failed to create app_offline : {e.Message}"),
retryCount: 3,
- retryDelayMilliseconds: 100);
+ retryDelayMilliseconds: RetryDelay.Milliseconds);
RemoveAppOffline(deploymentResult.ContentRoot);
}
@@ -218,7 +221,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
() => File.Delete(Path.Combine(appPath, "app_offline.htm")),
e => Logger.LogError($"Failed to remove app_offline : {e.Message}"),
retryCount: 3,
- retryDelayMilliseconds: 100);
+ retryDelayMilliseconds: RetryDelay.Milliseconds);
}
private async Task AssertAppOffline(IISDeploymentResult deploymentResult, string expectedResponse = "The app is offline.")
@@ -229,6 +232,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
{
// Keep retrying until app_offline is present.
response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
+ await Task.Delay(RetryDelay);
}
Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
diff --git a/test/Common.FunctionalTests/CommonStartupTests.cs b/test/Common.FunctionalTests/CommonStartupTests.cs
new file mode 100644
index 0000000000..760c1ad04b
--- /dev/null
+++ b/test/Common.FunctionalTests/CommonStartupTests.cs
@@ -0,0 +1,48 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
+using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
+using Microsoft.AspNetCore.Testing.xunit;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
+{
+ [Collection(PublishedSitesCollection.Name)]
+ public class CommonStartupTests : IISFunctionalTestBase
+ {
+ private readonly PublishedSitesFixture _fixture;
+
+ public CommonStartupTests(PublishedSitesFixture fixture)
+ {
+ _fixture = fixture;
+ }
+
+ public static TestMatrix TestVariants
+ => TestMatrix.ForServers(DeployerSelector.ServerType)
+ .WithTfms(Tfm.NetCoreApp22)
+ .WithAllApplicationTypes()
+ .WithAllAncmVersions()
+ .WithAllHostingModels();
+
+ [ConditionalTheory]
+ [MemberData(nameof(TestVariants))]
+ public async Task StartupStress(TestVariant variant)
+ {
+ var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
+
+ var deploymentResult = await DeployAsync(deploymentParameters);
+
+ await Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => {
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Equal("Hello World", response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
+ });
+ }
+ }
+}
diff --git a/test/CommonLibTests/FileOutputManagerTests.cpp b/test/CommonLibTests/FileOutputManagerTests.cpp
index d0caa524a8..ae1085408c 100644
--- a/test/CommonLibTests/FileOutputManagerTests.cpp
+++ b/test/CommonLibTests/FileOutputManagerTests.cpp
@@ -41,7 +41,7 @@ namespace FileOutManagerStartupTests
wprintf(expected, out);
}
- for (auto & p : std::experimental::filesystem::directory_iterator(tempDirectory.path()))
+ for (auto & p : std::filesystem::directory_iterator(tempDirectory.path()))
{
std::wstring filename(p.path().filename());
ASSERT_EQ(filename.substr(0, fileNamePrefix.size()), fileNamePrefix);
diff --git a/test/CommonLibTests/GlobalVersionTests.cpp b/test/CommonLibTests/GlobalVersionTests.cpp
index 9c74b6720e..f38c9361d2 100644
--- a/test/CommonLibTests/GlobalVersionTests.cpp
+++ b/test/CommonLibTests/GlobalVersionTests.cpp
@@ -7,7 +7,7 @@
namespace GlobalVersionTests
{
using ::testing::Test;
- namespace fs = std::experimental::filesystem;
+ namespace fs = std::filesystem;
class GlobalVersionTest : public Test
{
diff --git a/test/CommonLibTests/Helpers.cpp b/test/CommonLibTests/Helpers.cpp
index 3e429a6665..ccca6cad5b 100644
--- a/test/CommonLibTests/Helpers.cpp
+++ b/test/CommonLibTests/Helpers.cpp
@@ -28,7 +28,7 @@ TempDirectory::TempDirectory()
RPC_CSTR szUuid = NULL;
if (UuidToStringA(&uuid, &szUuid) == RPC_S_OK)
{
- m_path = std::experimental::filesystem::temp_directory_path() / szUuid;
+ m_path = std::filesystem::temp_directory_path() / reinterpret_cast(szUuid);
RpcStringFreeA(&szUuid);
return;
}
@@ -37,5 +37,5 @@ TempDirectory::TempDirectory()
TempDirectory::~TempDirectory()
{
- std::experimental::filesystem::remove_all(m_path);
+ std::filesystem::remove_all(m_path);
}
diff --git a/test/CommonLibTests/Helpers.h b/test/CommonLibTests/Helpers.h
index 657766dd43..67256966bb 100644
--- a/test/CommonLibTests/Helpers.h
+++ b/test/CommonLibTests/Helpers.h
@@ -18,11 +18,11 @@ public:
~TempDirectory();
- std::experimental::filesystem::path path() const
+ std::filesystem::path path() const
{
return m_path;
}
private:
- std::experimental::filesystem::path m_path;
+ std::filesystem::path m_path;
};
diff --git a/tools/update_schema.ps1 b/tools/update_schema.ps1
index 64f8248af4..2a45a3152c 100644
--- a/tools/update_schema.ps1
+++ b/tools/update_schema.ps1
@@ -15,10 +15,7 @@ $ancmSchemaFiles = @(
"aspnetcore_schema_v2.xml"
)
-$ancmSchemaFileLocations = @(
- @(Resolve-Path "$PSScriptRoot\..\src\AspNetCoreModuleV1\AspNetCore\aspnetcore_schema.xml"),
- @(Resolve-Path "$PSScriptRoot\..\src\AspNetCoreModuleV2\AspNetCore\aspnetcore_schema_v2.xml")
-)
+$ancmSchemaFileLocation = Resolve-Path "$PSScriptRoot\..\src\AspNetCoreModuleV2\AspNetCore\aspnetcore_schema_v2.xml";
[bool]$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
@@ -46,7 +43,7 @@ if (-not $isAdmin -and -not $WhatIfPreference) {
for ($i=0; $i -lt $ancmSchemaFiles.Length; $i++)
{
$schemaFile = $ancmSchemaFiles[$i]
- $schemaSource = $ancmSchemaFileLocations[$i]
+ $schemaSource = $ancmSchemaFileLocation
$destinations = @(
"${env:ProgramFiles(x86)}\IIS Express\config\schema\",