Aquire exclusive lock when creating application info (#1142)
This commit is contained in:
parent
1d1b2155c4
commit
477fd1d90d
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
|
<InProcessTestSite>true</InProcessTestSite>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -44,24 +44,40 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
|
||||||
// key in the applicationInfoHash.
|
// key in the applicationInfoHash.
|
||||||
pszApplicationId = pApplication.GetApplicationId();
|
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);
|
// When accessing the m_pApplicationInfoHash, we need to acquire the application manager
|
||||||
m_fDebugInitialize = TRUE;
|
// lock to avoid races on setting state.
|
||||||
}
|
SRWSharedLock readLock(m_srwLock);
|
||||||
|
if (!m_fDebugInitialize)
|
||||||
|
{
|
||||||
|
DebugInitializeFromConfig(m_pHttpServer, pApplication);
|
||||||
|
m_fDebugInitialize = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_fInShutdown)
|
if (g_fInShutdown)
|
||||||
{
|
{
|
||||||
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
|
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)
|
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);
|
pApplicationInfo = new APPLICATION_INFO(m_pHttpServer);
|
||||||
|
|
||||||
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pApplication));
|
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pApplication));
|
||||||
|
|
@ -187,7 +203,7 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
|
||||||
DWORD dwPreviousCounter = 0;
|
DWORD dwPreviousCounter = 0;
|
||||||
APPLICATION_INFO_HASH* table = NULL;
|
APPLICATION_INFO_HASH* table = NULL;
|
||||||
CONFIG_CHANGE_CONTEXT context;
|
CONFIG_CHANGE_CONTEXT context;
|
||||||
|
|
||||||
if (g_fInShutdown)
|
if (g_fInShutdown)
|
||||||
{
|
{
|
||||||
// We are already shutting down, ignore this event as a global configuration change event
|
// We are already shutting down, ignore this event as a global configuration change event
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue