Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorteicher2004-03-31 13:35:04 +0000
committerteicher2004-03-31 13:35:04 +0000
commit058e6f554c9480032ffb13b167a712a22b9ea719 (patch)
tree37a5544a03898a0844dacb6e843698d00f17d109 /org.eclipse.ui.editors
parent737147ab2079e6ee9499e0554488f671cdbd717f (diff)
downloadeclipse.platform.text-058e6f554c9480032ffb13b167a712a22b9ea719.tar.gz
eclipse.platform.text-058e6f554c9480032ffb13b167a712a22b9ea719.tar.xz
eclipse.platform.text-058e6f554c9480032ffb13b167a712a22b9ea719.zip
fixes bug 56871: [implementation] ConcurrentModificationException is thrown occasionally at IDocumentProvider::add/removeElementStateListener()
Diffstat (limited to 'org.eclipse.ui.editors')
-rw-r--r--org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/quickdiff/LastSaveReferenceProvider.java54
1 files changed, 47 insertions, 7 deletions
diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/quickdiff/LastSaveReferenceProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/quickdiff/LastSaveReferenceProvider.java
index 7c8cd34dd..c6942354d 100644
--- a/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/quickdiff/LastSaveReferenceProvider.java
+++ b/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/quickdiff/LastSaveReferenceProvider.java
@@ -25,11 +25,14 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.editors.text.IStorageDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IElementStateListener;
@@ -67,6 +70,8 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
* operation, or <code>null</code>.
*/
private IProgressMonitor fProgressMonitor;
+ /** The text editor we run upon. */
+ private ITextEditor fEditor;
/**
* A job to put the reading of file contents into a background.
@@ -109,21 +114,22 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
* {@inheritdoc}
*/
public void dispose() {
- IDocumentProvider provider= fDocumentProvider;
- if (provider != null)
- provider.removeElementStateListener(this);
-
IProgressMonitor monitor= fProgressMonitor;
if (monitor != null) {
monitor.setCanceled(true);
}
+ IDocumentProvider provider= fDocumentProvider;
+
synchronized (fLock) {
+ if (provider != null)
+ provider.removeElementStateListener(this);
fEditorInput= null;
fDocumentProvider= null;
fReference= null;
fDocumentRead= false;
fProgressMonitor= null;
+ fEditor= null;
}
}
@@ -145,11 +151,13 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
input= targetEditor.getEditorInput();
}
+
// dispose if the editor input or document provider have changed
// note that they may serve multiple editors
if (provider != fDocumentProvider || input != fEditorInput) {
dispose();
synchronized (fLock) {
+ fEditor= targetEditor;
fDocumentProvider= provider;
fEditorInput= input;
}
@@ -184,6 +192,7 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
IDocumentProvider prov= fDocumentProvider;
IEditorInput inp= fEditorInput;
IDocument doc= fReference;
+ ITextEditor editor= fEditor;
if (prov instanceof IStorageDocumentProvider && inp instanceof IFileEditorInput) {
@@ -196,9 +205,6 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
else
return;
- // addElementStateListener adds at most once - no problem to call
- // repeatedly
- ((IDocumentProvider) provider).addElementStateListener(this);
IJobManager jobMgr= Platform.getJobManager();
IFile file= input.getFile();
@@ -243,6 +249,7 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
// been updated in between (dispose or setActiveEditor)
fReference= doc;
fDocumentRead= true;
+ addElementStateListener(editor, prov);
}
}
}
@@ -251,6 +258,39 @@ public class LastSaveReferenceProvider implements IQuickDiffProviderImplementati
/* utility methods */
/**
+ * Adds this as element state listener in the UI thread as it can otherwise
+ * conflict with other listener additions, since DocumentProvider is not
+ * threadsafe.
+ *
+ * @param editor the editor to get the display from
+ * @param provider the document provider to register as element state listener
+ */
+ private void addElementStateListener(ITextEditor editor, final IDocumentProvider provider) {
+ // addElementStateListener adds at most once - no problem to call
+ // repeatedly
+ Runnable runnable= new Runnable() {
+ public void run() {
+ synchronized (fLock) {
+ if (fDocumentProvider == provider)
+ provider.addElementStateListener(LastSaveReferenceProvider.this);
+ }
+ }
+ };
+
+ Display display= null;
+ if (editor != null) {
+ IWorkbenchPartSite site= editor.getSite();
+ if (site != null)
+ site.getWorkbenchWindow().getShell().getDisplay();
+ }
+
+ if (display != null && !display.isDisposed())
+ display.asyncExec(runnable);
+ else
+ runnable.run();
+ }
+
+ /**
* Gets the contents of <code>file</code> as an input stream.
*
* @param file the <code>IFile</code> which we want the content for

Back to the top