Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Kubitz2021-10-24 16:03:18 +0000
committerJörg Kubitz2022-02-06 20:31:29 +0000
commit61ad084847ff1fe178a5b8f55c3ec7e64e358014 (patch)
tree2e39b09cb157dbee81b26152229bbc45ef774f73
parenta965822c2c3d24fc50ef5191e9208b6b49ad1a8b (diff)
downloadeclipse.platform.text-61ad084847ff1fe178a5b8f55c3ec7e64e358014.tar.gz
eclipse.platform.text-61ad084847ff1fe178a5b8f55c3ec7e64e358014.tar.xz
eclipse.platform.text-61ad084847ff1fe178a5b8f55c3ec7e64e358014.zip
Bug 575864 - Add API to wake up AbstractReconciler.BackgroundThreadI20220206-1800
Avoid that Reconciler sleeps while receiver is waiting Change-Id: I582fd963815748e1f9e14a1f9f5313cbe53ca627 Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/186867 Tested-by: Platform Bot <platform-bot@eclipse.org>
-rw-r--r--org.eclipse.jface.text.tests/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java2
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/AbstractReconcilerTest.java14
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/FastAbstractReconcilerTest.java29
-rw-r--r--org.eclipse.jface.text/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java74
6 files changed, 105 insertions, 18 deletions
diff --git a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
index 0ac00e4dd9f..36a3e53c7eb 100644
--- a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
@@ -16,7 +16,7 @@ Export-Package:
org.eclipse.jface.text.tests.templates.persistence,
org.eclipse.jface.text.tests.util
Require-Bundle:
- org.eclipse.jface.text;bundle-version="[3.19.0,4.0.0)",
+ org.eclipse.jface.text;bundle-version="[3.20.0,4.0.0)",
org.eclipse.jface;bundle-version="[3.5.0,4.0.0)",
org.junit;bundle-version="4.12.0",
org.eclipse.text.tests;bundle-version="[3.5.0,4.0.0)",
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
index 9668ad7342d..5ea29e85179 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
@@ -25,6 +25,7 @@ import org.eclipse.jface.text.tests.contentassist.ContextInformationTest;
import org.eclipse.jface.text.tests.contentassist.FilteringAsyncContentAssistTests;
import org.eclipse.jface.text.tests.contentassist.IncrementalAsyncContentAssistTests;
import org.eclipse.jface.text.tests.reconciler.AbstractReconcilerTest;
+import org.eclipse.jface.text.tests.reconciler.FastAbstractReconcilerTest;
import org.eclipse.jface.text.tests.rules.DefaultPartitionerTest;
import org.eclipse.jface.text.tests.rules.DefaultPartitionerZeroLengthTest;
import org.eclipse.jface.text.tests.rules.FastPartitionerTest;
@@ -59,6 +60,7 @@ import org.eclipse.jface.text.tests.templates.persistence.TemplatePersistenceDat
ContextInformationPresenterTest.class,
AbstractReconcilerTest.class,
+ FastAbstractReconcilerTest.class,
DefaultPartitionerTest.class,
DefaultPartitionerZeroLengthTest.class,
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/AbstractReconcilerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/AbstractReconcilerTest.java
index 134c59d4b0e..9778c251510 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/AbstractReconcilerTest.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/AbstractReconcilerTest.java
@@ -164,6 +164,10 @@ public class AbstractReconcilerTest {
fCallLog.add("reconcilerDocumentChanged");
}
@Override
+ protected void aboutToWork() {
+ AbstractReconcilerTest.this.aboutToWork(this);
+ }
+ @Override
protected void aboutToBeReconciled() {
fCallLog.add("aboutToBeReconciled");
}
@@ -177,7 +181,7 @@ public class AbstractReconcilerTest {
}
};
fReconciler.setIsIncrementalReconciler(false);
- fReconciler.setDelay(50); // make tests run faster
+ fReconciler.setDelay(getDelay());
fProgressMonitor= new NullProgressMonitor();
fReconciler.setProgressMonitor(fProgressMonitor);
@@ -190,6 +194,14 @@ public class AbstractReconcilerTest {
fAccessor= new Accessor(object, object.getClass());
}
+ int getDelay() {
+ return 50; // make tests run faster
+ }
+
+ void aboutToWork(@SuppressWarnings("unused") AbstractReconciler reconciler) {
+ // nothing
+ }
+
@After
public void tearDown() throws Exception {
fBarrier.shutdown();
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/FastAbstractReconcilerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/FastAbstractReconcilerTest.java
new file mode 100644
index 00000000000..e68fc857a34
--- /dev/null
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/reconciler/FastAbstractReconcilerTest.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Joerg Kubitz.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Joerg Kubitz - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.tests.reconciler;
+
+import org.eclipse.jface.text.reconciler.AbstractReconciler;
+
+public class FastAbstractReconcilerTest extends AbstractReconcilerTest {
+
+ @Override
+ int getDelay() {
+ return 10000; // make tests run slower (too slow without signalWaitForFinish)
+ }
+
+ @Override
+ void aboutToWork(AbstractReconciler reconciler) {
+ reconciler.signalWaitForFinish(); // make tests run faster (instant)
+ }
+}
diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF
index 377e97e3900..bf15c525c29 100644
--- a/org.eclipse.jface.text/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jface.text
-Bundle-Version: 3.19.100.qualifier
+Bundle-Version: 3.20.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package:
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
index 8b61857ba42..296dc543606 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
@@ -113,6 +113,7 @@ abstract public class AbstractReconciler implements IReconciler {
* emptied the dirty region queue.
*/
public void suspendCallerWhileDirty() {
+ AbstractReconciler.this.signalWaitForFinish();
boolean isDirty;
do {
synchronized (fDirtyRegionQueue) {
@@ -150,6 +151,7 @@ abstract public class AbstractReconciler implements IReconciler {
}
}
+ informNotFinished();
reconcilerReset();
}
@@ -164,12 +166,7 @@ abstract public class AbstractReconciler implements IReconciler {
@Override
public void run() {
- synchronized (fDirtyRegionQueue) {
- try {
- fDirtyRegionQueue.wait(fDelay);
- } catch (InterruptedException x) {
- }
- }
+ delay();
if (fCanceled)
return;
@@ -178,12 +175,7 @@ abstract public class AbstractReconciler implements IReconciler {
while (!fCanceled) {
- synchronized (fDirtyRegionQueue) {
- try {
- fDirtyRegionQueue.wait(fDelay);
- } catch (InterruptedException x) {
- }
- }
+ delay();
if (fCanceled)
break;
@@ -238,7 +230,7 @@ abstract public class AbstractReconciler implements IReconciler {
if (fThread.isActive() || !fThread.isDirty() && fThread.isAlive()) {
if (!fIsAllowedToModifyDocument && Thread.currentThread() == fThread)
throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$
- aboutToBeReconciled();
+ aboutToBeReconciledInternal();
}
/*
@@ -292,7 +284,7 @@ abstract public class AbstractReconciler implements IReconciler {
fDocument.addDocumentListener(this);
if (!fThread.isDirty())
- aboutToBeReconciled();
+ aboutToBeReconciledInternal();
startReconciling();
}
@@ -306,6 +298,8 @@ abstract public class AbstractReconciler implements IReconciler {
private Listener fListener;
/** The background thread delay. */
private int fDelay= 500;
+ /** Signal that the the background thread should not delay. */
+ volatile boolean waitFinish;
/** Are there incremental reconciling strategies? */
private boolean fIsIncrementalReconciler= true;
/** The progress monitor used by this reconciler. */
@@ -527,6 +521,56 @@ abstract public class AbstractReconciler implements IReconciler {
}
/**
+ * Hook for subclasses which want to perform some action as soon as the reconciler starts work
+ * (initial or reconciling) or waiting.
+ * <p>
+ * Default implementation is to do nothing. Implementors may call
+ * {@link #signalWaitForFinish()}.
+ * </p>
+ *
+ * @since 3.20
+ * @see #signalWaitForFinish
+ */
+ protected void aboutToWork() {
+ }
+
+ /**
+ * Signal reconciling should finish as soon as possible.
+ *
+ * @since 3.20
+ * @see #aboutToWork
+ */
+ public void signalWaitForFinish() {
+ synchronized (fDirtyRegionQueue) {
+ waitFinish= true;
+ fDirtyRegionQueue.notifyAll(); // notify AbstractReconciler#delay about waitFinish
+ }
+ }
+
+ private void informNotFinished() {
+ waitFinish= false;
+ aboutToWork();
+ }
+
+ private void aboutToBeReconciledInternal() {
+ aboutToBeReconciled();
+ informNotFinished();
+ }
+
+
+ private void delay() {
+ synchronized (fDirtyRegionQueue) {
+ if (waitFinish) {
+ return; // do not delay when waiting;
+ }
+ try {
+ fDirtyRegionQueue.wait(fDelay);
+ } catch (InterruptedException x) {
+ }
+ }
+ }
+
+ /**
* This method is called on startup of the background activity. It is called only
* once during the life time of the reconciler. Clients may reimplement this method.
*/
@@ -542,7 +586,7 @@ abstract public class AbstractReconciler implements IReconciler {
if (fDocument != null) {
if (!fThread.isDirty()&& fThread.isAlive())
- aboutToBeReconciled();
+ aboutToBeReconciledInternal();
if (fThread.isActive())
fProgressMonitor.setCanceled(true);

Back to the top