Skip to content

Commit c7d0955

Browse files
committed
CVC4: register ShutdownHook for all SmtEngines, also after creating new ones.
And unregister the hook after deleting the SmtEngine.
1 parent 6ab315e commit c7d0955

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.concurrent.atomic.AtomicBoolean;
3939
import org.checkerframework.checker.nullness.qual.Nullable;
4040
import org.sosy_lab.common.ShutdownNotifier;
41+
import org.sosy_lab.common.ShutdownNotifier.ShutdownRequestListener;
4142
import org.sosy_lab.java_smt.api.BasicProverEnvironment;
4243
import org.sosy_lab.java_smt.api.BooleanFormula;
4344
import org.sosy_lab.java_smt.api.BooleanFormulaManager;
@@ -50,12 +51,27 @@
5051
class CVC4TheoremProver extends AbstractProverWithAllSat<Void>
5152
implements ProverEnvironment, BasicProverEnvironment<Void> {
5253

54+
private final class ShutdownHook implements ShutdownRequestListener {
55+
private final AtomicBoolean interrupted = new AtomicBoolean(false);
56+
57+
@Override
58+
public void shutdownRequested(String reason) {
59+
interrupted.set(true);
60+
while (interrupted.get()) { // flag is reset after leaving isUnsat()
61+
smtEngine.interrupt();
62+
try {
63+
Thread.sleep(10);
64+
} catch (InterruptedException e) {
65+
}
66+
}
67+
}
68+
}
69+
5370
private final CVC4FormulaCreator creator;
54-
private SmtEngine smtEngine;
71+
private SmtEngine smtEngine; // final except for SL theory
72+
private ShutdownHook hook; // final except for SL theory
5573
private boolean changedSinceLastSatQuery = false;
5674

57-
protected final AtomicBoolean interrupted = new AtomicBoolean(false);
58-
5975
/** Tracks formulas on the stack, needed for model generation. */
6076
protected final Deque<List<Expr>> assertedFormulas = new ArrayDeque<>();
6177

@@ -94,7 +110,7 @@ protected CVC4TheoremProver(
94110
assertedFormulas.push(new ArrayList<>()); // create initial level
95111

96112
setOptions(randomSeed, pOptions);
97-
registerShutdownHandler(pShutdownNotifier);
113+
hook = registerShutdownHandler(pShutdownNotifier);
98114
}
99115

100116
private void setOptions(int randomSeed, Set<ProverOptions> pOptions) {
@@ -122,18 +138,10 @@ protected void setOptionForIncremental() {
122138
// method SmtEngine::check(), which seems to take about 10 ms. When this is fixed in
123139
// CVC4, we can remove the Thread.sleep(10), the AtomicBoolean interrupted and the while
124140
// loop surrounding this block.
125-
private void registerShutdownHandler(ShutdownNotifier pShutdownNotifier) {
126-
pShutdownNotifier.register(
127-
(reason) -> {
128-
interrupted.set(true);
129-
while (interrupted.get()) {
130-
smtEngine.interrupt();
131-
try {
132-
Thread.sleep(10);
133-
} catch (InterruptedException e) {
134-
}
135-
}
136-
});
141+
private ShutdownHook registerShutdownHandler(ShutdownNotifier pShutdownNotifier) {
142+
ShutdownHook listener = new ShutdownHook();
143+
pShutdownNotifier.register(listener);
144+
return listener;
137145
}
138146

139147
/** import an expression from global context into this prover's context. */
@@ -204,8 +212,9 @@ private void setChanged() {
204212
closeAllModels();
205213
if (!incremental) {
206214
// create a new clean smtEngine
215+
shutdownNotifier.unregister(hook);
207216
smtEngine = new SmtEngine(exprManager);
208-
registerShutdownHandler(shutdownNotifier);
217+
hook = registerShutdownHandler(shutdownNotifier);
209218
}
210219
}
211220
}
@@ -241,10 +250,18 @@ public boolean isUnsat() throws InterruptedException, SolverException {
241250
smtEngine.assertFormula(importExpr(expr));
242251
}
243252
}
244-
Result result = smtEngine.checkSat();
245-
if (interrupted.get()) {
246-
interrupted.set(false); // Should we throw InterruptException?
253+
shutdownNotifier.shutdownIfNecessary();
254+
Result result;
255+
try {
256+
result = smtEngine.checkSat();
257+
} finally {
258+
hook.interrupted.set(false);
259+
shutdownNotifier.shutdownIfNecessary();
247260
}
261+
return convertSatResult(result);
262+
}
263+
264+
private boolean convertSatResult(Result result) throws InterruptedException, SolverException {
248265
if (result.isUnknown()) {
249266
if (result.whyUnknown().equals(Result.UnknownExplanation.INTERRUPTED)) {
250267
throw new InterruptedException();
@@ -299,6 +316,7 @@ public void close() {
299316
exportMapping.delete();
300317
// smtEngine.delete();
301318
exprManager.delete();
319+
shutdownNotifier.unregister(hook);
302320
closed = true;
303321
}
304322
}

0 commit comments

Comments
 (0)