package org.skywalking.apm.agent.core.plugin.interceptor.assist;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext;
import org.skywalking.apm.agent.core.plugin.interceptor.InterceptorException;
/**
* {@link NoConcurrencyAccessObject} is method invocation counter,
* when {@link #whenEnter(EnhancedClassInstanceContext, InstanceMethodInvokeContext)} , counter + 1;
* and when {@link #whenExist(EnhancedClassInstanceContext)} , counter -1;
* <p>
* When, and only when, the first enter and last exist, also meaning first access,
* the {@link #enter(EnhancedClassInstanceContext, InstanceMethodInvokeContext)}
* and {@link #exit()} are called.
*
* @author wusheng
*/
public abstract class NoConcurrencyAccessObject {
private static final String INVOKE_COUNTER_KEY = "__$invokeCounterKey";
public void whenEnter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
if (!context.isContain(INVOKE_COUNTER_KEY)) {
context.set(INVOKE_COUNTER_KEY, 0);
}
int counter = context.get(INVOKE_COUNTER_KEY,
Integer.class);
if (++counter == 1) {
enter(context, interceptorContext);
}
context.set(INVOKE_COUNTER_KEY, counter);
}
public void whenExist(EnhancedClassInstanceContext context) {
if (!context.isContain(INVOKE_COUNTER_KEY)) {
throw new InterceptorException(
"key=INVOKE_COUNTER_KEY not found is context. unexpected situation.");
}
int counter = context.get(INVOKE_COUNTER_KEY,
Integer.class);
if (--counter == 0) {
exit();
}
context.set(INVOKE_COUNTER_KEY, counter);
}
protected abstract void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext);
protected abstract void exit();
}