use of org.apache.cassandra.simulator.systems.InterceptedWait.InterceptedConditionWait in project cassandra by apache.
the class InterceptingMonitors method preMonitorEnter.
@Override
public void preMonitorEnter(Object monitor, float preMonitorDelayChance) {
if (disabled)
return;
Thread anyThread = Thread.currentThread();
if (!(anyThread instanceof InterceptibleThread))
return;
InterceptibleThread thread = (InterceptibleThread) anyThread;
if (!thread.isEvaluationDeterministic() && random.decide(preMonitorDelayChance)) {
// TODO (feature): hold a stack of threads already paused by the nemesis, and, if one of the threads
// is entering the monitor, put the contents of this stack into `waitingOn` for this monitor.
InterceptedConditionWait signal = new InterceptedConditionWait(NEMESIS, 0L, thread, interceptorOfWaits.captureWaitSite(thread), null);
thread.interceptWait(signal);
// save interrupt state to restore afterwards - new ones only arrive if terminating simulation
boolean wasInterrupted = Thread.interrupted();
signal.awaitThrowUncheckedOnInterrupt();
if (wasInterrupted)
thread.interrupt();
}
MonitorState state = state(monitor);
if (state.heldBy != thread) {
if (state.heldBy != null) {
if (!thread.isIntercepting() && disabled)
return;
else if (!thread.isIntercepting())
throw new AssertionError();
checkForDeadlock(thread, state.heldBy);
InterceptedMonitorWait wait = new InterceptedMonitorWait(UNBOUNDED_WAIT, 0L, state, thread, interceptorOfWaits.captureWaitSite(thread));
wait.suspendedMonitorDepth = 1;
state.waitOn(LOCK, wait);
thread.interceptWait(wait);
synchronized (wait) {
waitingOn.put(thread, monitor);
try {
wait.await();
} catch (InterruptedException e) {
throw new UncheckedInterruptedException(e);
} finally {
waitingOn.remove(thread);
}
}
state.restore(wait);
} else {
state.heldBy = thread;
state.depth = 1;
}
} else {
state.depth++;
}
}
Aggregations