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);
 			}
 		}
 	}