Making sure that the timeout feature exits gracefully.
[jpf-core.git] / src / main / gov / nasa / jpf / listener / VariableConflictTracker.java
index 24eb8743cf24eedce698b5f31fc58ea473a7c781..cee0d24b62df5953a0cc4fd8f58d32a54594fdaa 100644 (file)
@@ -45,6 +45,7 @@ public class VariableConflictTracker extends ListenerAdapter {
   private boolean trackLocationVar;
   private int timeout;
   private Timer timeoutTimer;
+  private TimeoutTask timeoutTask;
 
   private final String SET_LOCATION_METHOD = "setLocationMode";
   private final String LOCATION_VAR = "location.mode";
@@ -68,34 +69,39 @@ public class VariableConflictTracker extends ListenerAdapter {
     // Timeout is in minutes
     timeout = config.getInt("timeout", 0);
     timeoutTimer = null;
+    timeoutTask = null;
   }
 
   // Create a task for timer to do a timeout
   private class TimeoutTask extends TimerTask {
 
-    ThreadInfo ti;
+    VM vm;
+    Timer timer;
 
-    public TimeoutTask(ThreadInfo ti) {
-      this.ti = ti;
+    public TimeoutTask(VM vm, Timer timer) {
+      this.vm = vm;
+      this.timer = timer;
     }
 
     @Override
     public void run() {
       StringBuilder sb = new StringBuilder();
       sb.append("Execution timeout!\n");
+      ThreadInfo ti = this.vm.getCurrentThread();
       Instruction nextIns = ti.createAndThrowException("java.lang.RuntimeException", sb.toString());
       ti.setNextPC(nextIns);
+      this.cancel();
+      this.timer.cancel();
     }
   }
 
   @Override
   public void instructionExecuted(VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn) {
     // Instantiate timeoutTimer
-    if (timeoutTimer == null && timeout > 0) {
-      ThreadList threads = vm.getThreadList();
-      ThreadInfo mainThread = threads.getThreadInfoForId(0);
+    if (timeout > 0 && timeoutTimer == null && timeoutTask == null) {
       timeoutTimer = new Timer();
-      timeoutTimer.schedule(new TimeoutTask(mainThread), timeout * 60 * 1000);
+      timeoutTask = new TimeoutTask(vm, timeoutTimer);
+      timeoutTimer.schedule(timeoutTask, timeout * 60 * 1000);
     }
 
     // CASE #1: Detecting variable write-after-write conflict