The DONE state detection logic in replayMessages() was flawed, as
we checked the current state, which is guaranteed to be SuccessorState.
We should be checking the previous state, available from the successor
state. As it turns out we can do this very cleanly by setting the flag
when the successor state gets the previous state assigned.
This also has better performance, as we do not touch the volatile
field multiple times.
Change-Id: Ica2246160bf8fee7aa134bbacb45857235405f6a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
+ return Verify.verifyNotNull(prevState, "Attempted to access previous state, which was not set");
}
void setPrevState(final State prevState) {
Verify.verify(this.prevState == null, "Attempted to set previous state to %s when we already have %s",
prevState, this.prevState);
this.prevState = Preconditions.checkNotNull(prevState);
}
void setPrevState(final State prevState) {
Verify.verify(this.prevState == null, "Attempted to set previous state to %s when we already have %s",
prevState, this.prevState);
this.prevState = Preconditions.checkNotNull(prevState);
+ // We cannot have duplicate successor states, so this check is sufficient
+ this.done = DONE.equals(prevState);
}
// To be called from safe contexts, where successor is known to be completed
}
// To be called from safe contexts, where successor is known to be completed
final SuccessorState local = getSuccessorState();
final State prevState = local.getPrevState();
final SuccessorState local = getSuccessorState();
final State prevState = local.getPrevState();
- final boolean isDone = DONE.equals(state)
- || state instanceof SuccessorState && ((SuccessorState) state).isDone();
final AbstractProxyTransaction successor = successorHistory.createTransactionProxy(getIdentifier(),
final AbstractProxyTransaction successor = successorHistory.createTransactionProxy(getIdentifier(),
- isSnapshotOnly(), isDone);
+ isSnapshotOnly(), local.isDone());
LOG.debug("{} created successor {}", this, successor);
local.setSuccessor(successor);
LOG.debug("{} created successor {}", this, successor);
local.setSuccessor(successor);