diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp index ccbd586f3e..2919b7cf4c 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp @@ -187,12 +187,6 @@ APPLICATION_INFO::EnsureApplicationCreated( // one optimization for failure scenario is to reduce the lock scope SRWExclusiveLock lock(m_srwLock); - if (m_fDoneAppCreation) - { - // application is NULL and CreateApplication failed previously - FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE); - } - else { if (m_pApplication != NULL) { diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs index 56b04c208e..020ef00213 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs +++ b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs @@ -1,6 +1,8 @@ // 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.Collections.Generic; +using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; @@ -38,5 +40,29 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { Assert.DoesNotContain(@"\\?\", await _fixture.Client.GetStringAsync("/BasePath")); } + + [ConditionalFact] + public async Task GetServerVariableDoesNotCrash() + { + async Task RunRequests() + { + var client = new HttpClient() { BaseAddress = _fixture.Client.BaseAddress }; + + for (int j = 0; j < 10; j++) + { + var response = await client.GetStringAsync("/GetServerVariableStress"); + Assert.StartsWith("Response Begin", response); + Assert.EndsWith("Response End", response); + } + } + + List tasks = new List(); + for (int i = 0; i < 10; i++) + { + tasks.Add(Task.Run(RunRequests)); + } + + await Task.WhenAll(tasks); + } } } diff --git a/test/WebSites/InProcessWebSite/Startup.cs b/test/WebSites/InProcessWebSite/Startup.cs index 3aaba9b44f..2bf89384f8 100644 --- a/test/WebSites/InProcessWebSite/Startup.cs +++ b/test/WebSites/InProcessWebSite/Startup.cs @@ -738,5 +738,21 @@ namespace IISTestSite ctx.RequestServices.GetService().StopApplication(); }); } + + private async Task GetServerVariableStress(HttpContext context) + { + // This test simulates the scenario where native Flush call is being + // executed on background thread while request thread calls GetServerVariable + // concurrent native calls may cause native object corruption + + await context.Response.WriteAsync("Response Begin"); + for (int i = 0; i < 1000; i++) + { + await context.Response.WriteAsync(context.GetIISServerVariable("REMOTE_PORT")); + await context.Response.Body.FlushAsync(); + } + await context.Response.WriteAsync("Response End"); + } + } }