Add a lock to ProxyTypeEmitter (#90)

Attempt resolving race conditions as seen in aspnet/Hosting1312
This commit is contained in:
Jass Bagga 2018-03-06 17:03:36 -08:00 коммит произвёл GitHub
Родитель d0d74c983a
Коммит 4b3d588f66
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 27 добавлений и 3 удалений

Просмотреть файл

@ -14,6 +14,7 @@ namespace Microsoft.Extensions.DiagnosticAdapter.Internal
public static class ProxyTypeEmitter
{
private static readonly Type[] EmptyTypes = new Type[0];
private static object _lock = new object();
public static Type GetProxyType(ProxyTypeCache cache, Type targetType, Type sourceType)
{
@ -164,8 +165,11 @@ namespace Microsoft.Extensions.DiagnosticAdapter.Internal
}
else
{
// We need to proxy each of the elements. Let's generate a type.
GenerateProxyTypeForList(elementKey.Item1, elementKey.Item2, proxyType, verificationResult);
lock (_lock)
{
// We need to proxy each of the elements. Let's generate a type.
GenerateProxyTypeForList(elementKey.Item1, elementKey.Item2, proxyType, verificationResult);
}
}
return true;
@ -241,7 +245,10 @@ namespace Microsoft.Extensions.DiagnosticAdapter.Internal
}
verificationResult.Mappings = propertyMappings;
GenerateProxyTypeFromProperties(sourceType, targetType, verificationResult);
lock (_lock)
{
GenerateProxyTypeFromProperties(sourceType, targetType, verificationResult);
}
return true;
}

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.DiagnosticAdapter.Internal
@ -623,6 +624,22 @@ namespace Microsoft.Extensions.DiagnosticAdapter.Internal
Assert.Equal("Billy", proxy[0][0][0].FirstName);
}
[Fact]
public void GetProxyType_LocksPreventDuplicateAssemblyNamesArgumentException_ForConcurrentThreads()
{
for (var i = 0; i < 5; i++)
{
Parallel.For(
0,
100,
(j) =>
{
var testObject = new Person();
ProxyTypeEmitter.GetProxyType(new ProxyTypeCache(), typeof(IPerson), testObject.GetType());
});
}
}
private object ConvertTo(object value, Type type)
{
var cache = new ProxyTypeCache();