[Fixes #11183] Race condition in RouteBase.EnsureLoggers
This commit is contained in:
parent
af2f647d63
commit
f652c22202
|
|
@ -3,20 +3,19 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.AspNetCore.Routing.Logging;
|
using Microsoft.AspNetCore.Routing.Logging;
|
||||||
using Microsoft.AspNetCore.Routing.Template;
|
using Microsoft.AspNetCore.Routing.Template;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.ObjectPool;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public abstract class RouteBase : IRouter, INamedRouter
|
public abstract class RouteBase : IRouter, INamedRouter
|
||||||
{
|
{
|
||||||
|
private readonly object _loggersLock = new object();
|
||||||
|
|
||||||
private TemplateMatcher _matcher;
|
private TemplateMatcher _matcher;
|
||||||
private TemplateBinder _binder;
|
private TemplateBinder _binder;
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
|
|
@ -259,11 +258,25 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
private void EnsureLoggers(HttpContext context)
|
private void EnsureLoggers(HttpContext context)
|
||||||
{
|
{
|
||||||
|
// We check first using the _logger to see if the loggers have been initialized to avoid taking
|
||||||
|
// the lock on the most common case.
|
||||||
if (_logger == null)
|
if (_logger == null)
|
||||||
{
|
{
|
||||||
var factory = context.RequestServices.GetRequiredService<ILoggerFactory>();
|
// We need to lock here to ensure that _constraintLogger and _logger get initialized atomically.
|
||||||
_logger = factory.CreateLogger(typeof(RouteBase).FullName);
|
lock (_loggersLock)
|
||||||
_constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
|
{
|
||||||
|
if (_logger != null)
|
||||||
|
{
|
||||||
|
// Multiple threads might have tried to accquire the lock at the same time. Technically
|
||||||
|
// there is nothing wrong if things get reinitialized by a second thread, but its easy
|
||||||
|
// to prevent by just rechecking and returning here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var factory = context.RequestServices.GetRequiredService<ILoggerFactory>();
|
||||||
|
_constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
|
||||||
|
_logger = factory.CreateLogger(typeof(RouteBase).FullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue