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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -38,7 +38,7 @@ namespace SharpRefactoring @@ -38,7 +38,7 @@ namespace SharpRefactoring
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);
if (!results.Any())

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

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

Loading…
Cancel
Save