diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs index 579f7f9fd..ba3024d3e 100644 --- a/Mono.Cecil.Cil/MethodBody.cs +++ b/Mono.Cecil.Cil/MethodBody.cs @@ -53,7 +53,12 @@ public MetadataToken LocalVarToken { } public Collection Instructions { - get { return instructions ?? (instructions = new InstructionCollection (method)); } + get { + if (instructions == null) + Interlocked.CompareExchange (ref instructions, new InstructionCollection (method), null); + + return instructions; + } } public bool HasExceptionHandlers { @@ -61,7 +66,12 @@ public bool HasExceptionHandlers { } public Collection ExceptionHandlers { - get { return exceptions ?? (exceptions = new Collection ()); } + get { + if (exceptions == null) + Interlocked.CompareExchange (ref exceptions, new Collection (), null); + + return exceptions; + } } public bool HasVariables { @@ -69,7 +79,12 @@ public bool HasVariables { } public Collection Variables { - get { return variables ?? (variables = new VariableDefinitionCollection ()); } + get { + if (variables == null) + Interlocked.CompareExchange (ref variables, new VariableDefinitionCollection (), null); + + return variables; + } } public ParameterDefinition ThisParameter { diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs index f1f85a0a6..9c095af52 100644 --- a/Mono.Cecil.Cil/Symbols.cs +++ b/Mono.Cecil.Cil/Symbols.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; +using System.Threading; using SR = System.Reflection; using Mono.Collections.Generic; @@ -118,7 +119,12 @@ public bool HasScopes { } public Collection Scopes { - get { return scopes ?? (scopes = new Collection ()); } + get { + if (scopes == null) + Interlocked.CompareExchange (ref scopes, new Collection (), null); + + return scopes; + } } public bool HasVariables { @@ -126,7 +132,12 @@ public bool HasVariables { } public Collection Variables { - get { return variables ?? (variables = new Collection ()); } + get { + if (variables == null) + Interlocked.CompareExchange (ref variables, new Collection (), null); + + return variables; + } } public bool HasConstants { @@ -134,7 +145,12 @@ public bool HasConstants { } public Collection Constants { - get { return constants ?? (constants = new Collection ()); } + get { + if (constants == null) + Interlocked.CompareExchange (ref constants, new Collection (), null); + + return constants; + } } internal ScopeDebugInformation () @@ -259,7 +275,12 @@ public bool HasCustomDebugInformations { } public Collection CustomDebugInformations { - get { return custom_infos ?? (custom_infos = new Collection ()); } + get { + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; + } } internal DebugInformation () @@ -409,7 +430,13 @@ public bool HasTargets { } public Collection Targets { - get { return targets ?? (targets = new Collection ()); } + get + { + if (targets == null) + Interlocked.CompareExchange (ref targets, new Collection (), null); + + return targets; + } } public ImportDebugInformation Parent { @@ -488,11 +515,21 @@ public InstructionOffset CatchHandler { } public Collection Yields { - get { return yields ?? (yields = new Collection ()); } + get { + if (yields == null) + Interlocked.CompareExchange (ref yields, new Collection (), null); + + return yields; + } } public Collection Resumes { - get { return resumes ?? (resumes = new Collection ()); } + get { + if (resumes == null) + Interlocked.CompareExchange (ref resumes, new Collection (), null); + + return resumes; + } } public Collection ResumeMethods { @@ -641,7 +678,12 @@ public bool HasSequencePoints { } public Collection SequencePoints { - get { return sequence_points ?? (sequence_points = new Collection ()); } + get { + if (sequence_points == null) + Interlocked.CompareExchange (ref sequence_points, new Collection (), null); + + return sequence_points; + } } public ScopeDebugInformation Scope { diff --git a/Mono.Cecil/ArrayType.cs b/Mono.Cecil/ArrayType.cs index 010049cc0..7413b1cba 100644 --- a/Mono.Cecil/ArrayType.cs +++ b/Mono.Cecil/ArrayType.cs @@ -10,6 +10,7 @@ using System; using System.Text; +using System.Threading; using Mono.Collections.Generic; using MD = Mono.Cecil.Metadata; @@ -57,8 +58,11 @@ public Collection Dimensions { if (dimensions != null) return dimensions; - dimensions = new Collection (); - dimensions.Add (new ArrayDimension ()); + var empty_dimensions = new Collection (); + empty_dimensions.Add (new ArrayDimension ()); + + Interlocked.CompareExchange (ref dimensions, empty_dimensions, null); + return dimensions; } } diff --git a/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil/AssemblyDefinition.cs index 264e9d862..93c9c9bd5 100644 --- a/Mono.Cecil/AssemblyDefinition.cs +++ b/Mono.Cecil/AssemblyDefinition.cs @@ -10,7 +10,7 @@ using System; using System.IO; - +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -46,7 +46,8 @@ public Collection Modules { if (main_module.HasImage) return main_module.Read (ref modules, this, (_, reader) => reader.ReadModules ()); - return modules = new Collection (1) { main_module }; + Interlocked.CompareExchange (ref modules, new Collection (1) { main_module }, null); + return modules; } } diff --git a/Mono.Cecil/AssemblyNameReference.cs b/Mono.Cecil/AssemblyNameReference.cs index 1d12cc163..168ad14da 100644 --- a/Mono.Cecil/AssemblyNameReference.cs +++ b/Mono.Cecil/AssemblyNameReference.cs @@ -12,6 +12,7 @@ using System.Globalization; using System.Security.Cryptography; using System.Text; +using System.Threading; namespace Mono.Cecil { @@ -84,20 +85,20 @@ public byte [] PublicKey { set { public_key = value; HasPublicKey = !public_key.IsNullOrEmpty (); - public_key_token = Empty.Array; + public_key_token = null; full_name = null; } } public byte [] PublicKeyToken { get { - if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) { + if (public_key_token == null && !public_key.IsNullOrEmpty ()) { var hash = HashPublicKey (); // we need the last 8 bytes in reverse order var local_public_key_token = new byte [8]; Array.Copy (hash, (hash.Length - 8), local_public_key_token, 0, 8); Array.Reverse (local_public_key_token, 0, 8); - public_key_token = local_public_key_token; // publish only once finished (required for thread-safety) + Interlocked.CompareExchange (ref public_key_token, local_public_key_token, null); // publish only once finished (required for thread-safety) } return public_key_token ?? Empty.Array; } @@ -160,7 +161,9 @@ public string FullName { builder.Append ("Retargetable=Yes"); } - return full_name = builder.ToString (); + Interlocked.CompareExchange (ref full_name, builder.ToString (), null); + + return full_name; } } diff --git a/Mono.Cecil/CustomAttribute.cs b/Mono.Cecil/CustomAttribute.cs index d64411fc2..c9cad8e5d 100644 --- a/Mono.Cecil/CustomAttribute.cs +++ b/Mono.Cecil/CustomAttribute.cs @@ -10,6 +10,7 @@ using System; using System.Diagnostics; +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -105,7 +106,10 @@ public Collection ConstructorArguments { get { Resolve (); - return arguments ?? (arguments = new Collection ()); + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; } } @@ -121,7 +125,10 @@ public Collection Fields { get { Resolve (); - return fields ?? (fields = new Collection ()); + if (fields == null) + Interlocked.CompareExchange (ref fields, new Collection (), null); + + return fields; } } @@ -137,7 +144,10 @@ public Collection Properties { get { Resolve (); - return properties ?? (properties = new Collection ()); + if (properties == null) + Interlocked.CompareExchange (ref properties, new Collection (), null); + + return properties; } } @@ -185,21 +195,26 @@ void Resolve () if (resolved || !HasImage) return; - Module.Read (this, (attribute, reader) => { - try { - reader.ReadCustomAttributeSignature (attribute); - resolved = true; - } catch (ResolutionException) { - if (arguments != null) - arguments.Clear (); - if (fields != null) - fields.Clear (); - if (properties != null) - properties.Clear (); - - resolved = false; - } - }); + lock (Module.SyncRoot) { + if (resolved) + return; + + Module.Read (this, (attribute, reader) => { + try { + reader.ReadCustomAttributeSignature (attribute); + resolved = true; + } catch (ResolutionException) { + if (arguments != null) + arguments.Clear (); + if (fields != null) + fields.Clear (); + if (properties != null) + properties.Clear (); + + resolved = false; + } + }); + } } } } diff --git a/Mono.Cecil/EventDefinition.cs b/Mono.Cecil/EventDefinition.cs index 33bc341ad..457ff4c7f 100644 --- a/Mono.Cecil/EventDefinition.cs +++ b/Mono.Cecil/EventDefinition.cs @@ -8,6 +8,7 @@ // Licensed under the MIT/X11 license. // +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -78,10 +79,10 @@ public Collection OtherMethods { InitializeMethods (); - if (other_methods != null) - return other_methods; + if (other_methods == null) + Interlocked.CompareExchange (ref other_methods, new Collection (), null); - return other_methods = new Collection (); + return other_methods; } } diff --git a/Mono.Cecil/FieldDefinition.cs b/Mono.Cecil/FieldDefinition.cs index 593b77e59..242e04ef2 100644 --- a/Mono.Cecil/FieldDefinition.cs +++ b/Mono.Cecil/FieldDefinition.cs @@ -9,6 +9,7 @@ // using System; +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -37,7 +38,11 @@ void ResolveLayout () return; } - offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); + lock (Module.SyncRoot) { + if (offset != Mixin.NotResolvedMarker) + return; + offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); + } } public bool HasLayoutInfo { @@ -76,7 +81,11 @@ void ResolveRVA () if (!HasImage) return; - rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); + lock (Module.SyncRoot) { + if (rva != Mixin.NotResolvedMarker) + return; + rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); + } } public int RVA { diff --git a/Mono.Cecil/GenericInstanceMethod.cs b/Mono.Cecil/GenericInstanceMethod.cs index e86a263d8..e3ff7db8e 100644 --- a/Mono.Cecil/GenericInstanceMethod.cs +++ b/Mono.Cecil/GenericInstanceMethod.cs @@ -10,7 +10,7 @@ using System; using System.Text; - +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -24,7 +24,12 @@ public bool HasGenericArguments { } public Collection GenericArguments { - get { return arguments ?? (arguments = new Collection ()); } + get { + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; + } } public override bool IsGenericInstance { diff --git a/Mono.Cecil/GenericInstanceType.cs b/Mono.Cecil/GenericInstanceType.cs index 888585085..745acd866 100644 --- a/Mono.Cecil/GenericInstanceType.cs +++ b/Mono.Cecil/GenericInstanceType.cs @@ -10,7 +10,7 @@ using System; using System.Text; - +using System.Threading; using Mono.Collections.Generic; using MD = Mono.Cecil.Metadata; @@ -26,7 +26,12 @@ public bool HasGenericArguments { } public Collection GenericArguments { - get { return arguments ?? (arguments = new Collection ()); } + get { + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; + } } public override TypeReference DeclaringType { diff --git a/Mono.Cecil/GenericParameter.cs b/Mono.Cecil/GenericParameter.cs index 17f219922..30dd73382 100644 --- a/Mono.Cecil/GenericParameter.cs +++ b/Mono.Cecil/GenericParameter.cs @@ -9,7 +9,7 @@ // using System; - +using System.Threading; using Mono.Collections.Generic; using Mono.Cecil.Metadata; @@ -60,7 +60,8 @@ public Collection Constraints { if (HasImage) return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter)); - return constraints = new GenericParameterConstraintCollection (this); + Interlocked.CompareExchange (ref constraints, new GenericParameterConstraintCollection (this), null); + return constraints; } } @@ -293,8 +294,11 @@ public bool HasCustomAttributes { public Collection CustomAttributes { get { - if (generic_parameter == null) - return custom_attributes = new Collection (); + if (generic_parameter == null) { + if (custom_attributes == null) + Interlocked.CompareExchange (ref custom_attributes, new Collection (), null); + return custom_attributes; + } return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, generic_parameter.Module)); } diff --git a/Mono.Cecil/ICustomAttributeProvider.cs b/Mono.Cecil/ICustomAttributeProvider.cs index 36d7ed018..894253098 100644 --- a/Mono.Cecil/ICustomAttributeProvider.cs +++ b/Mono.Cecil/ICustomAttributeProvider.cs @@ -9,6 +9,7 @@ // using System; +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -34,9 +35,11 @@ public static Collection GetCustomAttributes ( ref Collection variable, ModuleDefinition module) { - return module.HasImage () - ? module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider)) - : variable = new Collection(); + if (module.HasImage ()) + return module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider)); + + Interlocked.CompareExchange (ref variable, new Collection (), null); + return variable; } } } diff --git a/Mono.Cecil/IGenericParameterProvider.cs b/Mono.Cecil/IGenericParameterProvider.cs index 4c8dfc4da..b79169ed9 100644 --- a/Mono.Cecil/IGenericParameterProvider.cs +++ b/Mono.Cecil/IGenericParameterProvider.cs @@ -8,7 +8,7 @@ // Licensed under the MIT/X11 license. // - +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -48,9 +48,11 @@ public static Collection GetGenericParameters ( ref Collection collection, ModuleDefinition module) { - return module.HasImage () - ? module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider)) - : collection = new GenericParameterCollection (self); + if (module.HasImage ()) + return module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider)); + + Interlocked.CompareExchange (ref collection, new GenericParameterCollection (self), null); + return collection; } } } diff --git a/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil/MetadataSystem.cs index 7aa6fa8f5..749a39ca4 100644 --- a/Mono.Cecil/MetadataSystem.cs +++ b/Mono.Cecil/MetadataSystem.cs @@ -10,7 +10,8 @@ using System; using System.Collections.Generic; - +using System.Runtime.CompilerServices; +using System.Threading; using Mono.Cecil.Cil; using Mono.Cecil.Metadata; using Mono.Collections.Generic; @@ -68,7 +69,7 @@ sealed class MetadataSystem { static void InitializePrimitives () { - primitive_value_types = new Dictionary> (18, StringComparer.Ordinal) { + var types = new Dictionary> (18, StringComparer.Ordinal) { { "Void", new Row (ElementType.Void, false) }, { "Boolean", new Row (ElementType.Boolean, true) }, { "Char", new Row (ElementType.Char, true) }, @@ -88,6 +89,8 @@ static void InitializePrimitives () { "UIntPtr", new Row (ElementType.U, true) }, { "Object", new Row (ElementType.Object, false) }, }; + + Interlocked.CompareExchange (ref primitive_value_types, types, null); } public static void TryProcessPrimitiveTypeReference (TypeReference type) diff --git a/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil/MethodDefinition.cs index 76ce612d9..42bd8f3ea 100644 --- a/Mono.Cecil/MethodDefinition.cs +++ b/Mono.Cecil/MethodDefinition.cs @@ -9,6 +9,7 @@ // using System; +using System.Threading; using Mono.Cecil.Cil; using Mono.Collections.Generic; @@ -97,7 +98,12 @@ internal void ReadSemantics () if (!module.HasImage) return; - module.Read (this, (method, reader) => reader.ReadAllSemantics (method)); + lock (module.SyncRoot) { + if (sem_attrs_ready) + return; + + module.Read (this, (method, reader) => reader.ReadAllSemantics (method)); + } } public bool HasSecurityDeclarations { @@ -153,7 +159,9 @@ public MethodBody Body { if (HasImage && rva != 0) return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method)); - return body = new MethodBody (this); + Interlocked.CompareExchange (ref body, new MethodBody (this) , null); + + return body; } set { var module = this.Module; @@ -175,10 +183,11 @@ public MethodDebugInformation DebugInformation { get { Mixin.Read (Body); - if (debug_info != null) - return debug_info; + if (debug_info == null) { + Interlocked.CompareExchange (ref debug_info, new MethodDebugInformation (this), null); + } - return debug_info ?? (debug_info = new MethodDebugInformation (this)); + return debug_info; } set { debug_info = value; @@ -227,7 +236,9 @@ public Collection Overrides { if (HasImage) return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method)); - return overrides = new Collection (); + Interlocked.CompareExchange (ref overrides, new Collection (), null); + + return overrides; } } @@ -256,7 +267,10 @@ public Collection CustomDebugInformations { get { Mixin.Read (Body); - return custom_infos ?? (custom_infos = new Collection ()); + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; } } diff --git a/Mono.Cecil/MethodReference.cs b/Mono.Cecil/MethodReference.cs index bd5fb77ba..cc4391543 100644 --- a/Mono.Cecil/MethodReference.cs +++ b/Mono.Cecil/MethodReference.cs @@ -10,7 +10,7 @@ using System; using System.Text; - +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -47,7 +47,7 @@ public virtual bool HasParameters { public virtual Collection Parameters { get { if (parameters == null) - parameters = new ParameterDefinitionCollection (this); + Interlocked.CompareExchange (ref parameters, new ParameterDefinitionCollection (this), null); return parameters; } @@ -78,10 +78,10 @@ public virtual bool HasGenericParameters { public virtual Collection GenericParameters { get { - if (generic_parameters != null) - return generic_parameters; + if (generic_parameters == null) + Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null); - return generic_parameters = new GenericParameterCollection (this); + return generic_parameters; } } diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index 707a1358f..22daecb9b 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -428,7 +428,8 @@ public Collection AssemblyReferences { if (HasImage) return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ()); - return references = new Collection (); + Interlocked.CompareExchange (ref references, new Collection (), null); + return references; } } @@ -449,7 +450,8 @@ public Collection ModuleReferences { if (HasImage) return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ()); - return modules = new Collection (); + Interlocked.CompareExchange (ref modules, new Collection (), null); + return modules; } } @@ -473,7 +475,8 @@ public Collection Resources { if (HasImage) return Read (ref resources, this, (_, reader) => reader.ReadResources ()); - return resources = new Collection (); + Interlocked.CompareExchange (ref resources, new Collection (), null); + return resources; } } @@ -507,7 +510,8 @@ public Collection Types { if (HasImage) return Read (ref types, this, (_, reader) => reader.ReadTypes ()); - return types = new TypeDefinitionCollection (this); + Interlocked.CompareExchange (ref types, new TypeDefinitionCollection (this), null); + return types; } } @@ -528,7 +532,8 @@ public Collection ExportedTypes { if (HasImage) return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ()); - return exported_types = new Collection (); + Interlocked.CompareExchange (ref exported_types, new Collection (), null); + return exported_types; } } @@ -553,7 +558,10 @@ public bool HasCustomDebugInformations { public Collection CustomDebugInformations { get { - return custom_infos ?? (custom_infos = new Collection ()); + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; } } diff --git a/Mono.Cecil/PropertyDefinition.cs b/Mono.Cecil/PropertyDefinition.cs index 87f29475e..06b7bfdf7 100644 --- a/Mono.Cecil/PropertyDefinition.cs +++ b/Mono.Cecil/PropertyDefinition.cs @@ -9,7 +9,7 @@ // using System.Text; - +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -103,7 +103,8 @@ public Collection OtherMethods { if (other_methods != null) return other_methods; - return other_methods = new Collection (); + Interlocked.CompareExchange (ref other_methods, new Collection (), null); + return other_methods; } } diff --git a/Mono.Cecil/SecurityDeclaration.cs b/Mono.Cecil/SecurityDeclaration.cs index a18d14f25..99a66ee10 100644 --- a/Mono.Cecil/SecurityDeclaration.cs +++ b/Mono.Cecil/SecurityDeclaration.cs @@ -10,6 +10,7 @@ using System; using System.Diagnostics; +using System.Threading; using Mono.Collections.Generic; namespace Mono.Cecil { @@ -56,15 +57,25 @@ public bool HasFields { } public Collection Fields { - get { return fields ?? (fields = new Collection ()); } + get { + if (fields == null) + Interlocked.CompareExchange (ref fields, new Collection (), null); + + return fields; + } } public bool HasProperties { get { return !properties.IsNullOrEmpty (); } } + + public Collection Properties { + get { + if (properties == null) + Interlocked.CompareExchange (ref properties, new Collection (), null); - public Collection Properties { - get { return properties ?? (properties = new Collection ()); } + return properties; + } } public SecurityAttribute (TypeReference attributeType) @@ -108,7 +119,10 @@ public Collection SecurityAttributes { get { Resolve (); - return security_attributes ?? (security_attributes = new Collection ()); + if (security_attributes == null) + Interlocked.CompareExchange (ref security_attributes, new Collection (), null); + + return security_attributes; } } @@ -144,7 +158,7 @@ public byte [] GetBlob () if (!HasImage || signature == 0) throw new NotSupportedException (); - return blob = module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature)); + return module.Read (ref blob, this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature)); } void Resolve () @@ -152,8 +166,14 @@ void Resolve () if (resolved || !HasImage) return; - module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration)); - resolved = true; + lock (module.SyncRoot) { + + if (resolved) + return; + + module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration)); + resolved = true; + } } } @@ -171,9 +191,11 @@ public static Collection GetSecurityDeclarations ( ref Collection variable, ModuleDefinition module) { - return module.HasImage () - ? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider)) - : variable = new Collection(); + if (module.HasImage) + return module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider)); + + Interlocked.CompareExchange (ref variable, new Collection (), null); + return variable; } } } diff --git a/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil/TypeDefinition.cs index 6b6558c41..872e4c253 100644 --- a/Mono.Cecil/TypeDefinition.cs +++ b/Mono.Cecil/TypeDefinition.cs @@ -9,7 +9,7 @@ // using System; - +using System.Threading; using Mono.Cecil.Metadata; using Mono.Collections.Generic; @@ -61,19 +61,21 @@ public override string Name { void ResolveLayout () { - if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) - return; - if (!HasImage) { packing_size = Mixin.NoDataMarker; class_size = Mixin.NoDataMarker; return; } - var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type)); + lock (Module.SyncRoot) { + if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) + return; - packing_size = row.Col1; - class_size = row.Col2; + var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type)); + + packing_size = row.Col1; + class_size = row.Col2; + } } public bool HasLayoutInfo { @@ -128,7 +130,8 @@ public Collection Interfaces { if (HasImage) return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type)); - return interfaces = new InterfaceImplementationCollection (this); + Interlocked.CompareExchange (ref interfaces, new InterfaceImplementationCollection (this), null); + return interfaces; } } @@ -149,7 +152,8 @@ public Collection NestedTypes { if (HasImage) return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type)); - return nested_types = new MemberDefinitionCollection (this); + Interlocked.CompareExchange (ref nested_types, new MemberDefinitionCollection (this), null); + return nested_types; } } @@ -170,7 +174,8 @@ public Collection Methods { if (HasImage) return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type)); - return methods = new MemberDefinitionCollection (this); + Interlocked.CompareExchange (ref methods, new MemberDefinitionCollection (this) , null); + return methods; } } @@ -191,7 +196,8 @@ public Collection Fields { if (HasImage) return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type)); - return fields = new MemberDefinitionCollection (this); + Interlocked.CompareExchange (ref fields, new MemberDefinitionCollection (this), null); + return fields; } } @@ -212,7 +218,8 @@ public Collection Events { if (HasImage) return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type)); - return events = new MemberDefinitionCollection (this); + Interlocked.CompareExchange (ref events, new MemberDefinitionCollection (this), null); + return events; } } @@ -233,7 +240,8 @@ public Collection Properties { if (HasImage) return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type)); - return properties = new MemberDefinitionCollection (this); + Interlocked.CompareExchange (ref properties, new MemberDefinitionCollection (this), null); + return properties; } } @@ -511,8 +519,11 @@ public bool HasCustomAttributes { public Collection CustomAttributes { get { - if (type == null) - return custom_attributes = new Collection (); + if (type == null) { + if (custom_attributes == null) + Interlocked.CompareExchange (ref custom_attributes, new Collection (), null); + return custom_attributes; + } return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module)); } diff --git a/Mono.Cecil/TypeReference.cs b/Mono.Cecil/TypeReference.cs index c2643b671..e3fb5c58c 100644 --- a/Mono.Cecil/TypeReference.cs +++ b/Mono.Cecil/TypeReference.cs @@ -9,7 +9,7 @@ // using System; - +using System.Threading; using Mono.Cecil.Metadata; using Mono.Collections.Generic; @@ -123,10 +123,10 @@ public virtual bool HasGenericParameters { public virtual Collection GenericParameters { get { - if (generic_parameters != null) - return generic_parameters; - - return generic_parameters = new GenericParameterCollection (this); + if (generic_parameters == null) + Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null); + + return generic_parameters; } } @@ -172,11 +172,11 @@ public override string FullName { if (fullname != null) return fullname; - fullname = this.TypeFullName (); + var new_fullname = this.TypeFullName (); if (IsNested) - fullname = DeclaringType.FullName + "/" + fullname; - + new_fullname = DeclaringType.FullName + "/" + new_fullname; + Interlocked.CompareExchange (ref fullname, new_fullname, null); return fullname; } } diff --git a/Mono.Cecil/WindowsRuntimeProjections.cs b/Mono.Cecil/WindowsRuntimeProjections.cs index 04ba8c609..5ecd53c50 100644 --- a/Mono.Cecil/WindowsRuntimeProjections.cs +++ b/Mono.Cecil/WindowsRuntimeProjections.cs @@ -146,7 +146,8 @@ static Dictionary Projections if (projections != null) return projections; - return projections = new Dictionary { + + var new_projections = new Dictionary { { "AttributeTargets", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeTargets", "System.Runtime") }, { "AttributeUsageAttribute", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeUsageAttribute", "System.Runtime", attribute: true) }, { "Color", new ProjectionInfo ("Windows.UI", "Windows.UI", "Color", "System.Runtime.WindowsRuntime") }, @@ -198,6 +199,9 @@ static Dictionary Projections { "Vector3", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector3", "System.Numerics.Vectors") }, { "Vector4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector4", "System.Numerics.Vectors") }, }; + + Interlocked.CompareExchange (ref projections, new_projections, null); + return projections; } } diff --git a/Mono.Collections.Generic/ReadOnlyCollection.cs b/Mono.Collections.Generic/ReadOnlyCollection.cs index fe784149f..0ff232020 100644 --- a/Mono.Collections.Generic/ReadOnlyCollection.cs +++ b/Mono.Collections.Generic/ReadOnlyCollection.cs @@ -11,6 +11,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Threading; namespace Mono.Collections.Generic { @@ -19,7 +20,13 @@ public sealed class ReadOnlyCollection : Collection, ICollection, IList static ReadOnlyCollection empty; public static ReadOnlyCollection Empty { - get { return empty ?? (empty = new ReadOnlyCollection ()); } + get { + if (empty != null) + return empty; + + Interlocked.CompareExchange (ref empty, new ReadOnlyCollection (), null); + return empty; + } } bool ICollection.IsReadOnly {