Browse Source

Fixed thread-safety problem in DefaultReturnType.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4432 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
89c64e389c
  1. 36
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs

36
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs

@ -67,13 +67,19 @@ namespace ICSharpCode.SharpDevelop.Dom
return c; return c;
} }
bool getMembersBusy; // Required to prevent stack overflow when calling GetMethods() on a class with cyclic inheritance
// replaces old 'getMembersBusy' flag which wasn't thread-safe
[ThreadStatic] static BusyManager _busyManager;
static BusyManager busyManager {
get { return _busyManager ?? (_busyManager = new BusyManager()); }
}
public override List<IMethod> GetMethods() public override List<IMethod> GetMethods()
{ {
if (getMembersBusy) return new List<IMethod>();
getMembersBusy = true;
List<IMethod> l = new List<IMethod>(); List<IMethod> l = new List<IMethod>();
using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) {
l.AddRange(c.Methods); l.AddRange(c.Methods);
if (c.ClassType == ClassType.Interface) { if (c.ClassType == ClassType.Interface) {
if (c.BaseTypes.Count == 0) { if (c.BaseTypes.Count == 0) {
@ -86,7 +92,8 @@ namespace ICSharpCode.SharpDevelop.Dom
} else { } else {
AddMethodsFromBaseType(l, c.BaseType); AddMethodsFromBaseType(l, c.BaseType);
} }
getMembersBusy = false; }
}
return l; return l;
} }
@ -120,9 +127,9 @@ namespace ICSharpCode.SharpDevelop.Dom
public override List<IProperty> GetProperties() public override List<IProperty> GetProperties()
{ {
if (getMembersBusy) return new List<IProperty>();
getMembersBusy = true;
List<IProperty> l = new List<IProperty>(); List<IProperty> l = new List<IProperty>();
using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) {
l.AddRange(c.Properties); l.AddRange(c.Properties);
if (c.ClassType == ClassType.Interface) { if (c.ClassType == ClassType.Interface) {
foreach (IReturnType baseType in c.BaseTypes) { foreach (IReturnType baseType in c.BaseTypes) {
@ -131,7 +138,8 @@ namespace ICSharpCode.SharpDevelop.Dom
} else { } else {
AddPropertiesFromBaseType(l, c.BaseType); AddPropertiesFromBaseType(l, c.BaseType);
} }
getMembersBusy = false; }
}
return l; return l;
} }
@ -162,9 +170,9 @@ namespace ICSharpCode.SharpDevelop.Dom
public override List<IField> GetFields() public override List<IField> GetFields()
{ {
if (getMembersBusy) return new List<IField>();
getMembersBusy = true;
List<IField> l = new List<IField>(); List<IField> l = new List<IField>();
using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) {
l.AddRange(c.Fields); l.AddRange(c.Fields);
if (c.ClassType == ClassType.Interface) { if (c.ClassType == ClassType.Interface) {
foreach (IReturnType baseType in c.BaseTypes) { foreach (IReturnType baseType in c.BaseTypes) {
@ -176,15 +184,16 @@ namespace ICSharpCode.SharpDevelop.Dom
l.AddRange(baseType.GetFields()); l.AddRange(baseType.GetFields());
} }
} }
getMembersBusy = false; }
}
return l; return l;
} }
public override List<IEvent> GetEvents() public override List<IEvent> GetEvents()
{ {
if (getMembersBusy) return new List<IEvent>();
getMembersBusy = true;
List<IEvent> l = new List<IEvent>(); List<IEvent> l = new List<IEvent>();
using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) {
l.AddRange(c.Events); l.AddRange(c.Events);
if (c.ClassType == ClassType.Interface) { if (c.ClassType == ClassType.Interface) {
foreach (IReturnType baseType in c.BaseTypes) { foreach (IReturnType baseType in c.BaseTypes) {
@ -196,7 +205,8 @@ namespace ICSharpCode.SharpDevelop.Dom
l.AddRange(baseType.GetEvents()); l.AddRange(baseType.GetEvents());
} }
} }
getMembersBusy = false; }
}
return l; return l;
} }

Loading…
Cancel
Save