Skip to content

Commit 33edcfd

Browse files
committed
Fix pre-existing static constructor race
1 parent 95ef10a commit 33edcfd

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/Npgsql/TypeMapping/GlobalTypeMapper.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,20 @@ internal IEnumerable<PgTypeInfoResolverFactory> GetPluginResolverFactories()
4848

4949
internal void AddGlobalTypeMappingResolvers(PgTypeInfoResolverFactory[] factories, Func<PgTypeInfoResolverChainBuilder>? builderFactory = null, bool overwrite = false)
5050
{
51-
// Good enough logic to prevent SlimBuilder overriding the normal Builder.
52-
if (overwrite || factories.Length > _typeMappingResolvers.Length)
51+
_lock.EnterWriteLock();
52+
try
5353
{
54-
_builderFactory = builderFactory;
55-
_typeMappingResolvers = factories;
56-
ResetTypeMappingCache();
54+
// Prevent SlimBuilder from overriding the normal Builder.
55+
if (overwrite || factories.Length > _typeMappingResolvers.Length)
56+
{
57+
_builderFactory = builderFactory;
58+
_typeMappingResolvers = factories;
59+
ResetTypeMappingCache();
60+
}
61+
}
62+
finally
63+
{
64+
_lock.ExitWriteLock();
5765
}
5866
}
5967

@@ -67,12 +75,15 @@ PgSerializerOptions TypeMappingOptions
6775
{
6876
get
6977
{
70-
if (_typeMappingOptions is not null)
71-
return _typeMappingOptions;
78+
if (Volatile.Read(ref _typeMappingOptions) is { } options)
79+
return options;
7280

73-
_lock.EnterReadLock();
81+
_lock.EnterWriteLock();
7482
try
7583
{
84+
if (_typeMappingOptions is not null)
85+
return _typeMappingOptions;
86+
7687
var builder = _builderFactory?.Invoke() ?? new();
7788
builder.AppendResolverFactory(_userTypeMapper);
7889
foreach (var factory in _pluginResolverFactories)
@@ -90,7 +101,7 @@ PgSerializerOptions TypeMappingOptions
90101
}
91102
finally
92103
{
93-
_lock.ExitReadLock();
104+
_lock.ExitWriteLock();
94105
}
95106
}
96107
}

0 commit comments

Comments
 (0)