Skip to content

Commit 7058980

Browse files
committed
Better defense against cascading infinite snapshot recall
1 parent cc03085 commit 7058980

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

src/main/java/heronarts/lx/snapshot/LXSnapshotEngine.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ public boolean recall(LXGlobalSnapshot snapshot) {
436436
private boolean inRecall = false;
437437

438438
private final Queue<LXGlobalSnapshot> snapshotQueue = new ArrayDeque<>();
439+
private final List<LXGlobalSnapshot> snapshotChain = new ArrayList<>();
439440

440441
/**
441442
* Recall this snapshot, and populate an array of commands which
@@ -456,7 +457,7 @@ public boolean recall(LXGlobalSnapshot snapshot, List<LXCommand> commands) {
456457
// queue up the re-entrant snapshot recalls such that are all processed in the
457458
// order in which they were triggered.
458459
if (this.inRecall) {
459-
if (this.snapshotQueue.contains(snapshot)) {
460+
if (this.snapshotChain.contains(snapshot)) {
460461
LX.error("Ignoring infinite loop snapshot recall triggered by: " + snapshot);
461462
this.lx.pushError("Recall of " + snapshot.getLabel() + " creates an infinite loop, ignoring.");
462463
} else {
@@ -466,14 +467,18 @@ public boolean recall(LXGlobalSnapshot snapshot, List<LXCommand> commands) {
466467
}
467468

468469
this.inRecall = true;
470+
this.snapshotChain.clear();
471+
this.snapshotChain.add(snapshot);
469472
_recall(snapshot, commands);
470473

471474
// Process deferred re-entrant snapshot recalls
472475
LXGlobalSnapshot reentrant;
473-
while ((reentrant = this.snapshotQueue.peek()) != null) {
476+
while ((reentrant = this.snapshotQueue.poll()) != null) {
477+
this.snapshotChain.add(reentrant);
474478
_recall(reentrant, null);
475-
this.snapshotQueue.remove();
476479
}
480+
481+
this.snapshotChain.clear();
477482
this.inRecall = false;
478483
return true;
479484
}

0 commit comments

Comments
 (0)