22
33import java .util .Map ;
44import java .util .concurrent .ConcurrentHashMap ;
5+ import java .util .concurrent .TimeUnit ;
56
67import org .slf4j .Logger ;
78import org .slf4j .LoggerFactory ;
@@ -25,26 +26,26 @@ public class FlowDroidTimeoutWatcher implements IMemoryBoundedSolverStatusNotifi
2526 *
2627 */
2728 private enum SolverState {
28- /**
29- * The solver has not been started yet
30- */
31- IDLE ,
32- /**
33- * The solver is running
34- */
35- RUNNING ,
36- /**
37- * The solver has completed its work
38- */
39- DONE
29+ /**
30+ * The solver has not been started yet
31+ */
32+ IDLE ,
33+ /**
34+ * The solver is running
35+ */
36+ RUNNING ,
37+ /**
38+ * The solver has completed its work
39+ */
40+ DONE
4041 }
4142
4243 private final Logger logger = LoggerFactory .getLogger (getClass ());
4344
4445 private final long timeout ;
4546 private final InfoflowResults results ;
4647 private final Map <IMemoryBoundedSolver , SolverState > solvers = new ConcurrentHashMap <>();
47- private boolean stopped = false ;
48+ private volatile boolean stopped = false ;
4849 private ISolversTerminatedCallback terminationCallback = null ;
4950
5051 /**
@@ -93,7 +94,7 @@ public void addSolver(IMemoryBoundedSolver solver) {
9394 * Starts the timeout watcher
9495 */
9596 public void start () {
96- final long startTime = System .currentTimeMillis ();
97+ final long startTime = System .nanoTime ();
9798 logger .info ("FlowDroid timeout watcher started" );
9899 this .stopped = false ;
99100
@@ -103,34 +104,38 @@ public void start() {
103104 public void run () {
104105 // Sleep until we have reached the timeout
105106 boolean allTerminated = isTerminated ();
106- long timeElapsed = 0 ;
107107
108- while (!stopped && ((timeElapsed = System .currentTimeMillis () - startTime ) < 1000 * timeout )) {
108+ long timeoutNano = TimeUnit .SECONDS .toNanos (timeout );
109+ while (!stopped && ((System .nanoTime () - startTime ) < timeoutNano )) {
109110 allTerminated = isTerminated ();
110- if (allTerminated )
111+ if (allTerminated ) {
111112 break ;
113+ }
112114
113115 try {
114116 Thread .sleep (1000 );
115117 } catch (InterruptedException e ) {
116118 // There's little we can do here
117-
118119 }
119120 }
121+ long timeElapsed = TimeUnit .NANOSECONDS .toSeconds (System .nanoTime () - startTime );
120122
121123 // If things have not stopped on their own account, we force
122124 // them to
123125 if (!stopped & !allTerminated ) {
124126 logger .warn ("Timeout reached, stopping the solvers..." );
125- if (results != null )
127+ if (results != null ) {
126128 results .addException ("Timeout reached" );
129+ }
127130
128- TimeoutReason reason = new TimeoutReason (timeElapsed / 1000 , timeout );
129- for (IMemoryBoundedSolver solver : solvers .keySet ())
131+ TimeoutReason reason = new TimeoutReason (timeElapsed , timeout );
132+ for (IMemoryBoundedSolver solver : solvers .keySet ()) {
130133 solver .forceTerminate (reason );
134+ }
131135
132- if (terminationCallback != null )
136+ if (terminationCallback != null ) {
133137 terminationCallback .onSolversTerminated ();
138+ }
134139 }
135140
136141 logger .info ("FlowDroid timeout watcher terminated" );
0 commit comments