improve locking to avoid deadlocks
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/folding/DelegatingFoldingStructureProvider.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/folding/DelegatingFoldingStructureProvider.java
index bcf0e73..52ca90f 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/folding/DelegatingFoldingStructureProvider.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/folding/DelegatingFoldingStructureProvider.java
@@ -56,6 +56,8 @@
public class DelegatingFoldingStructureProvider implements
IFoldingStructureProvider, IFoldingStructureProviderExtension {
+ private static final boolean DEBUG = false;
+
/**
* A context that contains the information needed to compute the folding
* structure of an {@link ISourceModule}. Computed folding regions are
@@ -157,10 +159,10 @@
/**
* A {@link ProjectionAnnotation} for code.
*/
- protected static final class ScriptProjectionAnnotation extends
+ private static final class ScriptProjectionAnnotation extends
ProjectionAnnotation {
- private final AnnotationKey stamp;
+ final AnnotationKey stamp;
/**
* Creates a new projection annotation.
@@ -224,6 +226,9 @@
* Matches comments.
*/
private static final class CommentFilter implements Filter {
+ public CommentFilter() {
+ }
+
public boolean match(ScriptProjectionAnnotation annotation) {
if (annotation.getKind().isComment()
&& !annotation.isMarkedDeleted()) {
@@ -237,6 +242,9 @@
* Matches members.
*/
private static final class MemberFilter implements Filter {
+ public MemberFilter() {
+ }
+
public boolean match(ScriptProjectionAnnotation annotation) {
if (!annotation.isMarkedDeleted()
&& annotation.getElement() instanceof IMember) {
@@ -436,6 +444,9 @@
}
private class ElementChangedListener implements IElementChangedListener {
+ public ElementChangedListener() {
+ }
+
/*
* @see
* org.eclipse.dltk.core.IElementChangedListener#elementChanged(org.
@@ -633,9 +644,46 @@
return EditorUtility.getEditorInputModelElement(fEditor, false);
}
- private synchronized void update(FoldingStructureComputationContext ctx) {
+ static class Lock {
+
+ private boolean locked;
+
+ /**
+ * Tries to lock and returns <code>true</code> if attempt was successful
+ */
+ synchronized boolean lock() {
+ if (!locked) {
+ locked = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Unlocks
+ */
+ synchronized void unlock() {
+ locked = false;
+ }
+
+ }
+
+ private final Lock lock = new Lock();
+
+ protected void update(FoldingStructureComputationContext ctx) {
if (ctx == null)
return;
+ if (lock.lock()) {
+ try {
+ update0(ctx);
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ private void update0(FoldingStructureComputationContext ctx) {
Map<Annotation, Position> additions = new HashMap<Annotation, Position>();
List<Annotation> deletions = new ArrayList<Annotation>();
List<Annotation> updates = new ArrayList<Annotation>();
@@ -690,6 +738,11 @@
for (int i = 0; i < size; i++)
deletions.add(list.get(i).annotation);
}
+ if (DEBUG) {
+ System.out.println(getClass().getSimpleName() + ".update:"
+ + " additions=" + additions.size() + " deletions="
+ + deletions.size() + " updates=" + updates.size());
+ }
ctx.getModel().modifyAnnotations(
deletions.toArray(new Annotation[deletions.size()]), additions,
updates.toArray(new Annotation[updates.size()]));