Browse Source

Fixed thread-safety issue when accessing IProjectContent.ReferencedContents.

Fixes InvalidOperationException in XamlCompilationUnit.FindType (crash #240)
pull/6/merge
Daniel Grunwald 14 years ago
parent
commit
c5e470b7af
  1. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs
  2. 2
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/OptionPanels/ProjectImports.cs
  3. 2
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs
  4. 10
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs
  5. 2
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs
  6. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs
  7. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs
  8. 6
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/AddUsing.cs
  9. 4
      src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ResolveAttribute.cs
  10. 2
      src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ResolveExtensionMethod.cs
  11. 14
      src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs
  12. 7
      src/Main/Base/Project/Src/Util/ExtensionMethods.cs

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs

@ -4,6 +4,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.PythonBinding namespace ICSharpCode.PythonBinding
@ -118,7 +120,7 @@ namespace ICSharpCode.PythonBinding
public bool PartialNamespaceExistsInProjectReferences(string name) public bool PartialNamespaceExistsInProjectReferences(string name)
{ {
foreach (IProjectContent referencedContent in projectContent.ReferencedContents) { foreach (IProjectContent referencedContent in projectContent.ThreadSafeGetReferencedContents()) {
if (PartialNamespaceExists(referencedContent, name)) { if (PartialNamespaceExists(referencedContent, name)) {
return true; return true;
} }

2
src/AddIns/BackendBindings/VBNetBinding/Project/Src/OptionPanels/ProjectImports.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.VBNetBinding.OptionPanels
} }
IProjectContent projectContent = ParserService.GetProjectContent(project); IProjectContent projectContent = ParserService.GetProjectContent(project);
foreach(IProjectContent refProjectContent in projectContent.ReferencedContents) { foreach(IProjectContent refProjectContent in projectContent.ThreadSafeGetReferencedContents()) {
AddNamespaces(refProjectContent); AddNamespaces(refProjectContent);
} }

2
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataHelper.cs

@ -311,7 +311,7 @@ namespace ICSharpCode.XamlBinding
{ {
List<XmlnsCompletionItem> list = new List<XmlnsCompletionItem>(); List<XmlnsCompletionItem> list = new List<XmlnsCompletionItem>();
foreach (IProjectContent content in projectContent.ReferencedContents) { foreach (IProjectContent content in projectContent.ThreadSafeGetReferencedContents()) {
foreach (IAttribute att in content.GetAssemblyAttributes()) { foreach (IAttribute att in content.GetAssemblyAttributes()) {
if (att.PositionalArguments.Count == 2 if (att.PositionalArguments.Count == 2
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") { && att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") {

10
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompilationUnit.cs

@ -2,10 +2,12 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Linq;
using ICSharpCode.SharpDevelop.Dom;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.XamlBinding namespace ICSharpCode.XamlBinding
{ {
@ -81,7 +83,7 @@ namespace ICSharpCode.XamlBinding
IReturnType type = FindTypeInAssembly(pc, xmlNamespace, className); IReturnType type = FindTypeInAssembly(pc, xmlNamespace, className);
if (type != null) if (type != null)
return type; return type;
foreach (IProjectContent p in pc.ReferencedContents) { foreach (IProjectContent p in pc.ThreadSafeGetReferencedContents()) {
type = FindTypeInAssembly(p, xmlNamespace, className); type = FindTypeInAssembly(p, xmlNamespace, className);
if (type != null) if (type != null)
return type; return type;
@ -117,7 +119,7 @@ namespace ICSharpCode.XamlBinding
else { else {
var list = new List<ICompletionEntry>(); var list = new List<ICompletionEntry>();
AddNamespaceMembersInAssembly(pc, xmlNamespace, list); AddNamespaceMembersInAssembly(pc, xmlNamespace, list);
foreach (IProjectContent p in pc.ReferencedContents) { foreach (IProjectContent p in pc.ThreadSafeGetReferencedContents()) {
AddNamespaceMembersInAssembly(p, xmlNamespace, list); AddNamespaceMembersInAssembly(p, xmlNamespace, list);
} }
return list.OfType<IClass>(); return list.OfType<IClass>();

2
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.FormsDesigner.Services
try { try {
// load dependencies of current assembly // load dependencies of current assembly
foreach (IProjectContent rpc in pc.ReferencedContents) { foreach (IProjectContent rpc in pc.ThreadSafeGetReferencedContents()) {
if (rpc is ParseProjectContent) { if (rpc is ParseProjectContent) {
LoadAssembly(rpc); LoadAssembly(rpc);
} else if (rpc is ReflectionProjectContent) { } else if (rpc is ReflectionProjectContent) {

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.WpfDesign.AddIn
var pc = ParserService.CurrentProjectContent; var pc = ParserService.CurrentProjectContent;
var a = GetAssembly(pc); var a = GetAssembly(pc);
if (a != null) yield return a; if (a != null) yield return a;
foreach (var r in pc.ReferencedContents) { foreach (var r in pc.ThreadSafeGetReferencedContents()) {
a = GetAssembly(r); a = GetAssembly(r);
if (a != null) yield return a; if (a != null) yield return a;
} }

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.WpfDesign.AddIn
Assembly FindAssemblyInProjectReferences(IProjectContent pc, string name) Assembly FindAssemblyInProjectReferences(IProjectContent pc, string name)
{ {
foreach (IProjectContent referencedProjectContent in pc.ReferencedContents) { foreach (IProjectContent referencedProjectContent in pc.ThreadSafeGetReferencedContents()) {
if (name == referencedProjectContent.AssemblyName) { if (name == referencedProjectContent.AssemblyName) {
return this.typeResolutionService.LoadAssembly(referencedProjectContent); return this.typeResolutionService.LoadAssembly(referencedProjectContent);
} }

6
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/AddUsing.cs

@ -48,7 +48,7 @@ namespace SharpRefactoring.ContextActions
IProjectContent pc = context.ProjectContent; IProjectContent pc = context.ProjectContent;
SearchAllExtensionMethodsWithName(results, pc, rr.CallName); SearchAllExtensionMethodsWithName(results, pc, rr.CallName);
foreach (IProjectContent content in pc.ReferencedContents) foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents())
SearchAllExtensionMethodsWithName(results, content, rr.CallName); SearchAllExtensionMethodsWithName(results, content, rr.CallName);
foreach (IClass c in results) { foreach (IClass c in results) {
@ -99,7 +99,7 @@ namespace SharpRefactoring.ContextActions
public string Search(UnknownMethodResolveResult rr, IProjectContent pc, List<IClass> results) public string Search(UnknownMethodResolveResult rr, IProjectContent pc, List<IClass> results)
{ {
SearchAttributesWithName(results, pc, rr.CallName); SearchAttributesWithName(results, pc, rr.CallName);
foreach (IProjectContent content in pc.ReferencedContents) foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents())
SearchAttributesWithName(results, content, rr.CallName); SearchAttributesWithName(results, content, rr.CallName);
return rr.CallName; return rr.CallName;
} }
@ -107,7 +107,7 @@ namespace SharpRefactoring.ContextActions
public string Search(UnknownIdentifierResolveResult rr, IProjectContent pc, List<IClass> results) public string Search(UnknownIdentifierResolveResult rr, IProjectContent pc, List<IClass> results)
{ {
SearchAttributesWithName(results, pc, rr.Identifier); SearchAttributesWithName(results, pc, rr.Identifier);
foreach (IProjectContent content in pc.ReferencedContents) foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents())
SearchAttributesWithName(results, content, rr.Identifier); SearchAttributesWithName(results, content, rr.Identifier);
return rr.Identifier; return rr.Identifier;
} }

4
src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ResolveAttribute.cs

@ -42,7 +42,7 @@ namespace SharpRefactoring
var rr = context.ResolveResult as UnknownMethodResolveResult; var rr = context.ResolveResult as UnknownMethodResolveResult;
SearchAttributesWithName(results, pc, rr.CallName); SearchAttributesWithName(results, pc, rr.CallName);
foreach (IProjectContent content in pc.ReferencedContents) foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents())
SearchAttributesWithName(results, content, rr.CallName); SearchAttributesWithName(results, content, rr.CallName);
name = rr.CallName; name = rr.CallName;
@ -52,7 +52,7 @@ namespace SharpRefactoring
var rr = context.ResolveResult as UnknownIdentifierResolveResult; var rr = context.ResolveResult as UnknownIdentifierResolveResult;
SearchAttributesWithName(results, pc, rr.Identifier); SearchAttributesWithName(results, pc, rr.Identifier);
foreach (IProjectContent content in pc.ReferencedContents) foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents())
SearchAttributesWithName(results, content, rr.Identifier); SearchAttributesWithName(results, content, rr.Identifier);
name = rr.Identifier; name = rr.Identifier;

2
src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ResolveExtensionMethod.cs

@ -38,7 +38,7 @@ namespace SharpRefactoring
SearchAllExtensionMethodsWithName(results, context.ProjectContent, rr.CallName); SearchAllExtensionMethodsWithName(results, context.ProjectContent, rr.CallName);
foreach (IProjectContent content in context.ProjectContent.ReferencedContents) foreach (IProjectContent content in context.ProjectContent.ThreadSafeGetReferencedContents())
SearchAllExtensionMethodsWithName(results, content, rr.CallName); SearchAllExtensionMethodsWithName(results, content, rr.CallName);
if (!results.Any()) if (!results.Any())

14
src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs

@ -3,10 +3,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using System.IO;
using RegistryContentPair = System.Collections.Generic.KeyValuePair<ICSharpCode.SharpDevelop.Dom.ProjectContentRegistry, ICSharpCode.SharpDevelop.Dom.IProjectContent>; using RegistryContentPair = System.Collections.Generic.KeyValuePair<ICSharpCode.SharpDevelop.Dom.ProjectContentRegistry, ICSharpCode.SharpDevelop.Dom.IProjectContent>;
namespace ICSharpCode.SharpDevelop namespace ICSharpCode.SharpDevelop
@ -134,7 +136,7 @@ namespace ICSharpCode.SharpDevelop
foreach (ProjectContentRegistryDescriptor registry in registries) { foreach (ProjectContentRegistryDescriptor registry in registries) {
if (registry.IsRegistryLoaded) { if (registry.IsRegistryLoaded) {
foreach (IProjectContent pc in registry.Registry.GetLoadedProjectContents()) { foreach (IProjectContent pc in registry.Registry.GetLoadedProjectContents()) {
if (pc.ReferencedContents.Contains(referencedContent)) { if (pc.ThreadSafeGetReferencedContents().Contains(referencedContent)) {
if (unloadedReferenceContents.Add(pc)) { if (unloadedReferenceContents.Add(pc)) {
LoggingService.Debug("Mark dependent content for unloading " + pc); LoggingService.Debug("Mark dependent content for unloading " + pc);
otherContentsToUnload.Add(new RegistryContentPair(registry.Registry, pc)); otherContentsToUnload.Add(new RegistryContentPair(registry.Registry, pc));
@ -148,9 +150,11 @@ namespace ICSharpCode.SharpDevelop
IProject project = (IProject)pc.Project; IProject project = (IProject)pc.Project;
if (projectsToRefresh.Contains(project)) if (projectsToRefresh.Contains(project))
continue; continue;
if (pc.ReferencedContents.Remove(referencedContent)) { lock (pc.ReferencedContents) {
LoggingService.Debug("UnloadReferencedContent: Mark project for reparsing " + project.Name); if (pc.ReferencedContents.Remove(referencedContent)) {
projectsToRefresh.Add(project); LoggingService.Debug("UnloadReferencedContent: Mark project for reparsing " + project.Name);
projectsToRefresh.Add(project);
}
} }
} }

7
src/Main/Base/Project/Src/Util/ExtensionMethods.cs

@ -618,6 +618,13 @@ namespace ICSharpCode.SharpDevelop
return new Location(region.EndColumn, region.EndLine); return new Location(region.EndColumn, region.EndLine);
} }
public static IEnumerable<IProjectContent> ThreadSafeGetReferencedContents(this IProjectContent pc)
{
lock (pc.ReferencedContents) {
return pc.ReferencedContents.ToList();
}
}
public static int PositionToOffset(this IDocument document, Location location) public static int PositionToOffset(this IDocument document, Location location)
{ {
return document.PositionToOffset(location.Line, location.Column); return document.PositionToOffset(location.Line, location.Column);

Loading…
Cancel
Save