From 3d1356ae7b67433e6008624747daf5e65d0e91fd Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 4 May 2023 05:29:18 +0900 Subject: [PATCH] Fix race condition in GetName (#1571) --- .../Infrastructure/TypeExtensions.cs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/NJsonSchema/Infrastructure/TypeExtensions.cs b/src/NJsonSchema/Infrastructure/TypeExtensions.cs index 1cb69e3db..b031c1448 100644 --- a/src/NJsonSchema/Infrastructure/TypeExtensions.cs +++ b/src/NJsonSchema/Infrastructure/TypeExtensions.cs @@ -12,29 +12,49 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; +using System.Threading; namespace NJsonSchema.Infrastructure { /// Provides extension methods for reading contextual type names and descriptions. public static class TypeExtensions { + private static ReaderWriterLockSlim _namesLock = new ReaderWriterLockSlim(); private static Dictionary _names = new Dictionary(); /// Gets the name of the property for JSON serialization. /// The name. internal static string GetName(this ContextualAccessorInfo accessorInfo) { - if (!_names.ContainsKey(accessorInfo)) + _namesLock.EnterUpgradeableReadLock(); + try { - lock (_names) + if (_names.TryGetValue(accessorInfo, out var name)) { - if (!_names.ContainsKey(accessorInfo)) + return name; + } + + _namesLock.EnterWriteLock(); + try + { + if (_names.TryGetValue(accessorInfo, out name)) { - _names[accessorInfo] = GetNameWithoutCache(accessorInfo); + return name; } + + name = GetNameWithoutCache(accessorInfo); + _names[accessorInfo] = name; + return name; } + finally + { + _namesLock.ExitWriteLock(); + } + } + finally + { + _namesLock.ExitUpgradeableReadLock(); } - return _names[accessorInfo]; } private static string GetNameWithoutCache(ContextualAccessorInfo accessorInfo)