Skip to content

Commit 7c3ce29

Browse files
authored
Accessing GlobalTypeMapper.Mappings should be thread-safe (#3716)
1 parent f02df03 commit 7c3ce29

File tree

4 files changed

+46
-28
lines changed

4 files changed

+46
-28
lines changed

src/Npgsql/NpgsqlSchema.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
539539

540540
foreach (var baseType in connector.DatabaseInfo.BaseTypes)
541541
{
542-
if (!connector.TypeMapper.Mappings.TryGetValue(baseType.Name, out var mapping) &&
543-
!connector.TypeMapper.Mappings.TryGetValue(baseType.FullName, out mapping))
542+
if (!connector.TypeMapper.InternalMappings.TryGetValue(baseType.Name, out var mapping) &&
543+
!connector.TypeMapper.InternalMappings.TryGetValue(baseType.FullName, out mapping))
544544
continue;
545545

546546
var row = table.Rows.Add();
@@ -556,8 +556,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
556556

557557
foreach (var arrayType in connector.DatabaseInfo.ArrayTypes)
558558
{
559-
if (!connector.TypeMapper.Mappings.TryGetValue(arrayType.Element.Name, out var elementMapping) &&
560-
!connector.TypeMapper.Mappings.TryGetValue(arrayType.Element.FullName, out elementMapping))
559+
if (!connector.TypeMapper.InternalMappings.TryGetValue(arrayType.Element.Name, out var elementMapping) &&
560+
!connector.TypeMapper.InternalMappings.TryGetValue(arrayType.Element.FullName, out elementMapping))
561561
continue;
562562

563563
var row = table.Rows.Add();
@@ -577,8 +577,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
577577

578578
foreach (var rangeType in connector.DatabaseInfo.RangeTypes)
579579
{
580-
if (!connector.TypeMapper.Mappings.TryGetValue(rangeType.Subtype.Name, out var elementMapping) &&
581-
!connector.TypeMapper.Mappings.TryGetValue(rangeType.Subtype.FullName, out elementMapping))
580+
if (!connector.TypeMapper.InternalMappings.TryGetValue(rangeType.Subtype.Name, out var elementMapping) &&
581+
!connector.TypeMapper.InternalMappings.TryGetValue(rangeType.Subtype.FullName, out elementMapping))
582582
continue;
583583

584584
var row = table.Rows.Add();
@@ -598,8 +598,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
598598

599599
foreach (var enumType in connector.DatabaseInfo.EnumTypes)
600600
{
601-
if (!connector.TypeMapper.Mappings.TryGetValue(enumType.Name, out var mapping) &&
602-
!connector.TypeMapper.Mappings.TryGetValue(enumType.FullName, out mapping))
601+
if (!connector.TypeMapper.InternalMappings.TryGetValue(enumType.Name, out var mapping) &&
602+
!connector.TypeMapper.InternalMappings.TryGetValue(enumType.FullName, out mapping))
603603
continue;
604604

605605
var row = table.Rows.Add();
@@ -613,8 +613,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
613613

614614
foreach (var compositeType in connector.DatabaseInfo.CompositeTypes)
615615
{
616-
if (!connector.TypeMapper.Mappings.TryGetValue(compositeType.Name, out var mapping) &&
617-
!connector.TypeMapper.Mappings.TryGetValue(compositeType.FullName, out mapping))
616+
if (!connector.TypeMapper.InternalMappings.TryGetValue(compositeType.Name, out var mapping) &&
617+
!connector.TypeMapper.InternalMappings.TryGetValue(compositeType.FullName, out mapping))
618618
continue;
619619

620620
var row = table.Rows.Add();
@@ -628,8 +628,8 @@ static DataTable GetDataTypes(NpgsqlConnection conn)
628628

629629
foreach (var domainType in connector.DatabaseInfo.DomainTypes)
630630
{
631-
if (!connector.TypeMapper.Mappings.TryGetValue(domainType.BaseType.Name, out var baseMapping) &&
632-
!connector.TypeMapper.Mappings.TryGetValue(domainType.BaseType.FullName, out baseMapping))
631+
if (!connector.TypeMapper.InternalMappings.TryGetValue(domainType.BaseType.Name, out var baseMapping) &&
632+
!connector.TypeMapper.InternalMappings.TryGetValue(domainType.BaseType.FullName, out baseMapping))
633633
continue;
634634

635635
var row = table.Rows.Add();

src/Npgsql/TypeMapping/ConnectorTypeMapper.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace Npgsql.TypeMapping
1616
{
17-
class ConnectorTypeMapper : TypeMapperBase
17+
sealed class ConnectorTypeMapper : TypeMapperBase
1818
{
1919
/// <summary>
2020
/// The connector to which this type mapper belongs.
@@ -180,6 +180,8 @@ public override bool RemoveMapping(string pgTypeName)
180180
return true;
181181
}
182182

183+
public override IEnumerable<NpgsqlTypeMapping> Mappings => InternalMappings.Values;
184+
183185
void CheckReady()
184186
{
185187
if (_connector.State != ConnectorState.Ready)
@@ -192,9 +194,9 @@ void ResetMappings()
192194
globalMapper.Lock.EnterReadLock();
193195
try
194196
{
195-
Mappings.Clear();
196-
foreach (var kv in globalMapper.Mappings)
197-
Mappings.Add(kv.Key, kv.Value);
197+
InternalMappings.Clear();
198+
foreach (var kv in globalMapper.InternalMappings)
199+
InternalMappings.Add(kv.Key, kv.Value);
198200
}
199201
finally
200202
{
@@ -234,7 +236,7 @@ internal void Bind(NpgsqlDatabaseInfo databaseInfo)
234236

235237
void BindTypes()
236238
{
237-
foreach (var mapping in Mappings.Values)
239+
foreach (var mapping in InternalMappings.Values)
238240
BindType(mapping, _connector, externalCall: false);
239241

240242
// Enums
@@ -424,10 +426,10 @@ void BindRangeType(NpgsqlTypeHandler elementHandler, PostgresRangeType pgRangeTy
424426
}
425427

426428
bool TryGetMapping(PostgresType pgType, [NotNullWhen(true)] out NpgsqlTypeMapping? mapping)
427-
=> Mappings.TryGetValue(pgType.Name, out mapping) ||
428-
Mappings.TryGetValue(pgType.FullName, out mapping) ||
429+
=> InternalMappings.TryGetValue(pgType.Name, out mapping) ||
430+
InternalMappings.TryGetValue(pgType.FullName, out mapping) ||
429431
pgType is PostgresDomainType domain && (
430-
Mappings.TryGetValue(domain.BaseType.Name, out mapping) ||
431-
Mappings.TryGetValue(domain.BaseType.FullName, out mapping));
432+
InternalMappings.TryGetValue(domain.BaseType.Name, out mapping) ||
433+
InternalMappings.TryGetValue(domain.BaseType.FullName, out mapping));
432434
}
433435
}

src/Npgsql/TypeMapping/GlobalTypeMapper.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
namespace Npgsql.TypeMapping
2626
{
27-
class GlobalTypeMapper : TypeMapperBase
27+
sealed class GlobalTypeMapper : TypeMapperBase
2828
{
2929
public static GlobalTypeMapper Instance { get; }
3030

@@ -103,12 +103,28 @@ public override bool RemoveMapping(string pgTypeName)
103103
}
104104
}
105105

106+
public override IEnumerable<NpgsqlTypeMapping> Mappings
107+
{
108+
get
109+
{
110+
Lock.EnterReadLock();
111+
try
112+
{
113+
return InternalMappings.Values.ToArray();
114+
}
115+
finally
116+
{
117+
Lock.ExitReadLock();
118+
}
119+
}
120+
}
121+
106122
public override void Reset()
107123
{
108124
Lock.EnterWriteLock();
109125
try
110126
{
111-
Mappings.Clear();
127+
InternalMappings.Clear();
112128
SetupBuiltInHandlers();
113129
RecordChange();
114130
}

src/Npgsql/TypeMapping/TypeMapperBase.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Npgsql.TypeMapping
1010
{
1111
abstract class TypeMapperBase : INpgsqlTypeMapper
1212
{
13-
internal Dictionary<string, NpgsqlTypeMapping> Mappings { get; } = new();
13+
internal Dictionary<string, NpgsqlTypeMapping> InternalMappings { get; } = new();
1414

1515
public INpgsqlNameTranslator DefaultNameTranslator { get; }
1616

@@ -26,15 +26,15 @@ protected TypeMapperBase(INpgsqlNameTranslator defaultNameTranslator)
2626

2727
public virtual INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping)
2828
{
29-
if (Mappings.ContainsKey(mapping.PgTypeName))
29+
if (InternalMappings.ContainsKey(mapping.PgTypeName))
3030
RemoveMapping(mapping.PgTypeName);
31-
Mappings[mapping.PgTypeName] = mapping;
31+
InternalMappings[mapping.PgTypeName] = mapping;
3232
return this;
3333
}
3434

35-
public virtual bool RemoveMapping(string pgTypeName) => Mappings.Remove(pgTypeName);
35+
public virtual bool RemoveMapping(string pgTypeName) => InternalMappings.Remove(pgTypeName);
3636

37-
IEnumerable<NpgsqlTypeMapping> INpgsqlTypeMapper.Mappings => Mappings.Values;
37+
public abstract IEnumerable<NpgsqlTypeMapping> Mappings { get; }
3838

3939
public abstract void Reset();
4040

0 commit comments

Comments
 (0)