Bug 581462: Sometimes a script engine stalls and seems to be deadlocked
Change-Id: I3debb461b28eeb91a96c7fa159499dd5fc1240c9
diff --git a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractReplScriptEngine.java b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractReplScriptEngine.java
index 061b1c4..90c3ad0 100644
--- a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractReplScriptEngine.java
+++ b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractReplScriptEngine.java
@@ -55,8 +55,8 @@
// we can only set this before the engine got started
setSystem(!terminate);
- synchronized (this) {
- notifyAll();
+ synchronized (getScheduledScripts()) {
+ getScheduledScripts().notifyAll();
}
}
diff --git a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractScriptEngine.java b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractScriptEngine.java
index 42d79c4..24b93bd 100644
--- a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractScriptEngine.java
+++ b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractScriptEngine.java
@@ -82,8 +82,8 @@
}
}
- /** List of code junks to be executed. */
- private final List<Script> fScheduledScripts = Collections.synchronizedList(new ArrayList<Script>());
+ /** List of code parts to be executed. */
+ private final List<Script> fScheduledScripts = new ArrayList<>();
private final ListenerList<IExecutionListener> fExecutionListeners = new ListenerList<>();
@@ -135,10 +135,9 @@
public final ScriptResult execute(final Object content) {
final Script script = (content instanceof Script) ? (Script) content : new Script(content);
- fScheduledScripts.add(script);
-
- synchronized (this) {
- notifyAll();
+ synchronized (fScheduledScripts) {
+ fScheduledScripts.add(script);
+ fScheduledScripts.notifyAll();
}
return script.getResult();
@@ -237,19 +236,17 @@
// main loop
while (!shallTerminate()) {
- // execute code
- if (!fScheduledScripts.isEmpty()) {
- final Script piece = fScheduledScripts.remove(0);
- inject(piece, true, false);
+ try {
+ synchronized (fScheduledScripts) {
+ waitForNextScript();
- } else {
- synchronized (this) {
- try {
- Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine idle: " + getName());
- wait();
- } catch (final InterruptedException e) {
+ if (!fScheduledScripts.isEmpty()) {
+ final Script piece = fScheduledScripts.remove(0);
+ inject(piece, true, false);
}
}
+ } catch (final InterruptedException e) {
+ // waiting got interrupted, quite likely a shutdown
}
}
}
@@ -260,6 +257,15 @@
return cleanupRun(returnStatus);
}
+ private void waitForNextScript() throws InterruptedException {
+ synchronized (fScheduledScripts) {
+ while ((fScheduledScripts.isEmpty()) && (!shallTerminate())) {
+ Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine idle: " + getName());
+ fScheduledScripts.wait();
+ }
+ }
+ }
+
private IStatus setupRun() {
Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine started: " + getName());
@@ -294,9 +300,9 @@
synchronized (fScheduledScripts) {
for (final Script script : fScheduledScripts)
script.setException(new ScriptExecutionException("Engine got terminated"));
- }
- fScheduledScripts.clear();
+ fScheduledScripts.clear();
+ }
notifyExecutionListeners(null, IExecutionListener.ENGINE_END);
@@ -309,8 +315,8 @@
returnStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not teardown script engine", e);
}
} finally {
- synchronized (this) {
- notifyAll();
+ synchronized (fScheduledScripts) {
+ fScheduledScripts.notifyAll();
}
closeStreams();
@@ -365,7 +371,9 @@
* @return <code>true</code> when termination is requested or there is no more work to be done
*/
protected boolean shallTerminate() {
- return getMonitor().isCanceled() || fScheduledScripts.isEmpty();
+ synchronized (fScheduledScripts) {
+ return getMonitor().isCanceled() || fScheduledScripts.isEmpty();
+ }
}
@Override
@@ -376,8 +384,8 @@
terminateCurrent();
- synchronized (this) {
- notifyAll();
+ synchronized (fScheduledScripts) {
+ fScheduledScripts.notifyAll();
}
}
@@ -392,9 +400,9 @@
if (!Thread.currentThread().equals(getThread())) {
// we cannot join our own thread
- synchronized (this) {
+ synchronized (fScheduledScripts) {
while (!isFinished())
- wait(1000);
+ fScheduledScripts.wait(1000);
}
}
}
@@ -404,9 +412,9 @@
if (!Thread.currentThread().equals(getThread())) {
// we cannot join our own thread
- synchronized (this) {
+ synchronized (fScheduledScripts) {
if (!isFinished())
- wait(timeout);
+ fScheduledScripts.wait(timeout);
}
}
}