Skip to content

Commit f652c22

Browse files
authored
[Fixes #11183] Race condition in RouteBase.EnsureLoggers (#11218)
[Fixes #11183] Race condition in RouteBase.EnsureLoggers
1 parent af2f647 commit f652c22

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

src/Http/Routing/src/RouteBase.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Text.Encodings.Web;
76
using System.Threading.Tasks;
87
using Microsoft.AspNetCore.Http;
9-
using Microsoft.AspNetCore.Routing.Internal;
108
using Microsoft.AspNetCore.Routing.Logging;
119
using Microsoft.AspNetCore.Routing.Template;
1210
using Microsoft.Extensions.DependencyInjection;
1311
using Microsoft.Extensions.Logging;
14-
using Microsoft.Extensions.ObjectPool;
1512

1613
namespace Microsoft.AspNetCore.Routing
1714
{
1815
public abstract class RouteBase : IRouter, INamedRouter
1916
{
17+
private readonly object _loggersLock = new object();
18+
2019
private TemplateMatcher _matcher;
2120
private TemplateBinder _binder;
2221
private ILogger _logger;
@@ -259,11 +258,25 @@ private void EnsureBinder(HttpContext context)
259258

260259
private void EnsureLoggers(HttpContext context)
261260
{
261+
// We check first using the _logger to see if the loggers have been initialized to avoid taking
262+
// the lock on the most common case.
262263
if (_logger == null)
263264
{
264-
var factory = context.RequestServices.GetRequiredService<ILoggerFactory>();
265-
_logger = factory.CreateLogger(typeof(RouteBase).FullName);
266-
_constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
265+
// We need to lock here to ensure that _constraintLogger and _logger get initialized atomically.
266+
lock (_loggersLock)
267+
{
268+
if (_logger != null)
269+
{
270+
// Multiple threads might have tried to accquire the lock at the same time. Technically
271+
// there is nothing wrong if things get reinitialized by a second thread, but its easy
272+
// to prevent by just rechecking and returning here.
273+
return;
274+
}
275+
276+
var factory = context.RequestServices.GetRequiredService<ILoggerFactory>();
277+
_constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
278+
_logger = factory.CreateLogger(typeof(RouteBase).FullName);
279+
}
267280
}
268281
}
269282

0 commit comments

Comments
 (0)