From f1efcd8973ce4bfcd0e51ecc1c6f7e5a6be0bc99 Mon Sep 17 00:00:00 2001
From: Nelson Tavares de Sousa <stu103017@mail.uni-kiel.de>
Date: Tue, 19 May 2015 16:15:20 +0200
Subject: [PATCH] switched to semaphore instead of yields; added test

---
 src/main/java/teetime/framework/Analysis.java |  7 ++---
 .../framework/RunnableProducerStage.java      | 31 +++++++++----------
 .../framework/RunnableProducerStageTest.java  | 28 +++++++++++++++++
 .../teetime/framework/RunnableTestStage.java  | 25 +++++++++++++++
 4 files changed, 70 insertions(+), 21 deletions(-)
 create mode 100644 src/test/java/teetime/framework/RunnableProducerStageTest.java
 create mode 100644 src/test/java/teetime/framework/RunnableTestStage.java

diff --git a/src/main/java/teetime/framework/Analysis.java b/src/main/java/teetime/framework/Analysis.java
index cc143dcd..18b83787 100644
--- a/src/main/java/teetime/framework/Analysis.java
+++ b/src/main/java/teetime/framework/Analysis.java
@@ -29,7 +29,6 @@ import teetime.framework.exceptionHandling.AbstractExceptionListener;
 import teetime.framework.exceptionHandling.IExceptionListenerFactory;
 import teetime.framework.exceptionHandling.IgnoringExceptionListenerFactory;
 import teetime.framework.signal.InitializingSignal;
-import teetime.framework.signal.StartingSignal;
 import teetime.framework.signal.ValidatingSignal;
 import teetime.framework.validation.AnalysisNotValidException;
 import teetime.util.Pair;
@@ -266,15 +265,13 @@ public final class Analysis<T extends AnalysisConfiguration> implements Uncaught
 
 	private void sendInitializingSignal() {
 		for (RunnableProducerStage runnable : producerRunnables) {
-			InitializingSignal signal = new InitializingSignal();
-			runnable.sendInitializingSignal(signal);
+			runnable.sendInitializingSignal();
 		}
 	}
 
 	private void sendStartingSignal() {
 		for (RunnableProducerStage runnable : producerRunnables) {
-			StartingSignal signal = new StartingSignal();
-			runnable.sendStartingSignal(signal);
+			runnable.sendStartingSignal();
 		}
 	}
 
diff --git a/src/main/java/teetime/framework/RunnableProducerStage.java b/src/main/java/teetime/framework/RunnableProducerStage.java
index 8275f07f..14ce4563 100644
--- a/src/main/java/teetime/framework/RunnableProducerStage.java
+++ b/src/main/java/teetime/framework/RunnableProducerStage.java
@@ -15,22 +15,27 @@
  */
 package teetime.framework;
 
+import java.util.concurrent.Semaphore;
+
 import teetime.framework.signal.InitializingSignal;
 import teetime.framework.signal.StartingSignal;
 import teetime.framework.signal.TerminatingSignal;
 
 final class RunnableProducerStage extends AbstractRunnableStage {
 
-	private boolean initArrived, startArrived;
+	private final Semaphore startSemaphore = new Semaphore(0);
+	private final Semaphore initSemaphore = new Semaphore(0);
 
 	public RunnableProducerStage(final Stage stage) {
 		super(stage);
 	}
 
 	@Override
-	protected void beforeStageExecution() {
+	protected void beforeStageExecution() throws InterruptedException {
 		waitForInitializingSignal();
+		this.stage.onSignal(new InitializingSignal(), null);
 		waitForStartingSignal();
+		this.stage.onSignal(new StartingSignal(), null);
 	}
 
 	@Override
@@ -44,25 +49,19 @@ final class RunnableProducerStage extends AbstractRunnableStage {
 		this.stage.onSignal(terminatingSignal, null);
 	}
 
-	public void sendInitializingSignal(final InitializingSignal signal) {
-		this.stage.onSignal(signal, null);
-		initArrived = true;
+	public void sendInitializingSignal() {
+		initSemaphore.release();
 	}
 
-	public void sendStartingSignal(final StartingSignal signal) {
-		this.stage.onSignal(signal, null);
-		startArrived = true;
+	public void sendStartingSignal() {
+		startSemaphore.release();
 	}
 
-	public void waitForInitializingSignal() {
-		while (!initArrived) {
-			Thread.yield();
-		}
+	public void waitForInitializingSignal() throws InterruptedException {
+		initSemaphore.acquire();
 	}
 
-	public void waitForStartingSignal() {
-		while (!startArrived) {
-			Thread.yield();
-		}
+	public void waitForStartingSignal() throws InterruptedException {
+		startSemaphore.acquire();
 	}
 }
diff --git a/src/test/java/teetime/framework/RunnableProducerStageTest.java b/src/test/java/teetime/framework/RunnableProducerStageTest.java
new file mode 100644
index 00000000..db2fec7c
--- /dev/null
+++ b/src/test/java/teetime/framework/RunnableProducerStageTest.java
@@ -0,0 +1,28 @@
+package teetime.framework;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class RunnableProducerStageTest {
+
+	@Test
+	public void testInit() {
+		RunnableTestStage testStage = new RunnableTestStage();
+		RunnableProducerStage runnable = new RunnableProducerStage(testStage);
+		Thread thread = new Thread(runnable);
+		thread.start();
+		// Not running and not initialized
+		assertFalse(testStage.executed && testStage.initialized);
+		runnable.sendInitializingSignal();
+		// Not running, but initialized
+		assertFalse(testStage.executed && !testStage.initialized);
+		runnable.sendStartingSignal();
+
+		while (!testStage.shouldBeTerminated()) {
+			Thread.yield();
+		}
+		assertTrue(testStage.executed);
+	}
+}
diff --git a/src/test/java/teetime/framework/RunnableTestStage.java b/src/test/java/teetime/framework/RunnableTestStage.java
new file mode 100644
index 00000000..034474a3
--- /dev/null
+++ b/src/test/java/teetime/framework/RunnableTestStage.java
@@ -0,0 +1,25 @@
+package teetime.framework;
+
+
+class RunnableTestStage extends AbstractProducerStage<Object> {
+
+	boolean executed, initialized;
+
+	@Override
+	protected void executeStage() {
+		executed = true;
+		this.terminate();
+	}
+
+	@Override
+	protected void execute() {
+
+	}
+
+	@Override
+	public void onInitializing() throws Exception {
+		super.onInitializing();
+		initialized = true;
+	}
+
+}
-- 
GitLab