Make model access thread-safe
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -26,7 +27,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
public TypeInfo[] TypesByUsageIndex { get; }
|
public TypeInfo[] TypesByUsageIndex { get; }
|
||||||
|
|
||||||
// List of type usages that are initialized via pointers in the image
|
// List of type usages that are initialized via pointers in the image
|
||||||
public Dictionary<ulong, TypeInfo> TypesByVirtualAddress { get; } = new Dictionary<ulong, TypeInfo>();
|
public ConcurrentDictionary<ulong, TypeInfo> TypesByVirtualAddress { get; } = new ConcurrentDictionary<ulong, TypeInfo>();
|
||||||
|
|
||||||
// Every type
|
// Every type
|
||||||
public IEnumerable<TypeInfo> Types => new IEnumerable<TypeInfo>[] { TypesByDefinitionIndex, TypesByUsageIndex, TypesByVirtualAddress.Values }.SelectMany(t => t);
|
public IEnumerable<TypeInfo> Types => new IEnumerable<TypeInfo>[] { TypesByDefinitionIndex, TypesByUsageIndex, TypesByVirtualAddress.Values }.SelectMany(t => t);
|
||||||
@@ -35,7 +36,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
public MethodBase[] MethodsByDefinitionIndex { get; }
|
public MethodBase[] MethodsByDefinitionIndex { get; }
|
||||||
|
|
||||||
// List of all generated CustomAttributeData objects by their index into AttributeTypeIndices
|
// List of all generated CustomAttributeData objects by their index into AttributeTypeIndices
|
||||||
public Dictionary<int, CustomAttributeData> AttributesByIndices { get; } = new Dictionary<int, CustomAttributeData>();
|
public ConcurrentDictionary<int, CustomAttributeData> AttributesByIndices { get; } = new ConcurrentDictionary<int, CustomAttributeData>();
|
||||||
|
|
||||||
public Il2CppModel(Il2CppInspector package) {
|
public Il2CppModel(Il2CppInspector package) {
|
||||||
Package = package;
|
Package = package;
|
||||||
@@ -114,7 +115,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
var type = Package.BinaryImage.ReadMappedObject<Il2CppType>(ptr);
|
var type = Package.BinaryImage.ReadMappedObject<Il2CppType>(ptr);
|
||||||
var newUsage = getNewTypeUsage(type, MemberTypes.NestedType);
|
var newUsage = getNewTypeUsage(type, MemberTypes.NestedType);
|
||||||
|
|
||||||
TypesByVirtualAddress.Add(ptr, newUsage);
|
TypesByVirtualAddress.TryAdd(ptr, newUsage);
|
||||||
return newUsage;
|
return newUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,13 +49,19 @@ namespace Il2CppInspector.Reflection
|
|||||||
|
|
||||||
attribute = new CustomAttributeData { Index = customAttributeIndex, AttributeType = asm.Model.GetTypeFromUsage(typeIndex) };
|
attribute = new CustomAttributeData { Index = customAttributeIndex, AttributeType = asm.Model.GetTypeFromUsage(typeIndex) };
|
||||||
|
|
||||||
asm.Model.AttributesByIndices.Add(i, attribute);
|
asm.Model.AttributesByIndices.TryAdd(i, attribute);
|
||||||
yield return attribute;
|
yield return attribute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<CustomAttributeData> getCustomAttributes(Assembly asm, uint token, int customAttributeIndex)
|
private static readonly object gcaLock = new object();
|
||||||
=> getCustomAttributes(asm, asm.Model.GetCustomAttributeIndex(asm, token, customAttributeIndex)).ToList();
|
private static IList<CustomAttributeData> getCustomAttributes(Assembly asm, uint token, int customAttributeIndex) {
|
||||||
|
// Force the generation of the collection to be thread-safe
|
||||||
|
// Convert the result into a list for thread-safe enumeration
|
||||||
|
lock (gcaLock) {
|
||||||
|
return getCustomAttributes(asm, asm.Model.GetCustomAttributeIndex(asm, token, customAttributeIndex)).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static IList<CustomAttributeData> GetCustomAttributes(Assembly asm) => getCustomAttributes(asm, asm.AssemblyDefinition.token, asm.AssemblyDefinition.customAttributeIndex);
|
public static IList<CustomAttributeData> GetCustomAttributes(Assembly asm) => getCustomAttributes(asm, asm.AssemblyDefinition.token, asm.AssemblyDefinition.customAttributeIndex);
|
||||||
public static IList<CustomAttributeData> GetCustomAttributes(EventInfo evt) => getCustomAttributes(evt.Assembly, evt.Definition.token, evt.Definition.customAttributeIndex);
|
public static IList<CustomAttributeData> GetCustomAttributes(EventInfo evt) => getCustomAttributes(evt.Assembly, evt.Definition.token, evt.Definition.customAttributeIndex);
|
||||||
|
|||||||
Reference in New Issue
Block a user