From 0dd30412e2f48b47bb5725a310f18bb42e78631d Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Tue, 24 Mar 2026 14:00:44 +0100 Subject: [PATCH] Fix InitializeConstructors race condition --- .../Infrastructure/Impl/CmObjectSurrogate.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/SIL.LCModel/Infrastructure/Impl/CmObjectSurrogate.cs b/src/SIL.LCModel/Infrastructure/Impl/CmObjectSurrogate.cs index 69123547..e9a67288 100644 --- a/src/SIL.LCModel/Infrastructure/Impl/CmObjectSurrogate.cs +++ b/src/SIL.LCModel/Infrastructure/Impl/CmObjectSurrogate.cs @@ -33,6 +33,7 @@ namespace SIL.LCModel.Infrastructure.Impl internal sealed class CmObjectSurrogate : ICmObjectSurrogate //, IEquatable { private static Dictionary s_classToConstructorInfo; + private static readonly object s_constructorLock = new object(); /// /// It's common that hundreds of thousands of surrogates only use a few hundred class names. This is a local interning /// of those names. @@ -225,16 +226,19 @@ internal static CmObjectSurrogate CreateSnapshot(ICmObject obj) internal static void InitializeConstructors(List cmObjectTypes) { - if (s_classToConstructorInfo != null) return; - - s_classToConstructorInfo = new Dictionary(); - // Get default constructor. - // Only do this once, since they are stored in a static data member. - foreach (var lcmType in cmObjectTypes) + lock (s_constructorLock) { - if (lcmType.IsAbstract) continue; + if (s_classToConstructorInfo != null) return; + + s_classToConstructorInfo = new Dictionary(); + // Get default constructor. + // Only do this once, since they are stored in a static data member. + foreach (var lcmType in cmObjectTypes) + { + if (lcmType.IsAbstract) continue; - s_classToConstructorInfo.Add(lcmType.Name, lcmType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); + s_classToConstructorInfo.Add(lcmType.Name, lcmType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); + } } }