package php.runtime.env;
import php.runtime.Memory;
import php.runtime.exceptions.CriticalException;
import php.runtime.output.OutputBuffer;
import php.runtime.reflection.ClassEntity;
import php.runtime.reflection.ModuleEntity;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Set;
import java.util.Stack;
public class ConcurrentEnvironment extends Environment {
private ThreadLocal<Stack<OutputBuffer>> outputBuffers;
private ThreadLocal<Stack<Integer>> silentFlags = new ThreadLocal<Stack<Integer>>(){
@Override
protected Stack<Integer> initialValue() {
return new Stack<Integer>();
}
};
private ThreadLocal<CallStack> callStack = new ThreadLocal<CallStack>() {
@Override
protected CallStack initialValue() {
return new CallStack(ConcurrentEnvironment.this);
}
};
public ConcurrentEnvironment(Environment parent) {
super(parent);
}
public ConcurrentEnvironment(CompileScope scope, OutputStream output) {
super(scope, output);
}
public ConcurrentEnvironment(OutputStream output) {
super(output);
}
public ConcurrentEnvironment(CompileScope scope) {
super(scope);
}
@Override
public Stack<OutputBuffer> getOutputBuffers() {
if (outputBuffers == null) {
synchronized (this) {
outputBuffers = new ThreadLocal<Stack<OutputBuffer>>(){
@Override
protected Stack<OutputBuffer> initialValue() {
Stack stack = new Stack<OutputBuffer>();
stack.push(getDefaultBuffer());
return stack;
}
};
}
}
return outputBuffers.get();
}
@Override
public void __replaceCallStack(CallStack stack) {
callStack.set(stack);
}
@Override
public CallStack getCallStack() {
return callStack.get();
}
@Override
public void addIncludePath(String value) {
synchronized (this){
super.addIncludePath(value);
}
}
@Override
public ClassEntity autoloadCall(String name, String lowerName) {
synchronized (this) {
return super.autoloadCall(name, lowerName);
}
}
@Override
public void setIncludePaths(Set<String> includePaths) {
synchronized (this) {
super.setIncludePaths(includePaths);
}
}
@Override
public boolean defineConstant(String name, Memory value, boolean caseSensitise) {
synchronized (this) {
return super.defineConstant(name, value, caseSensitise);
}
}
@Override
public Memory setConfigValue(String name, Memory value) {
synchronized (this) {
return super.setConfigValue(name, value);
}
}
@Override
public void setLocale(Locale locale) {
synchronized (this) {
super.setLocale(locale);
}
}
@Override
public void setUserValue(String name, Object value) {
synchronized (this) {
super.setUserValue(name, value);
}
}
@Override
public void setErrorFlags(int errorFlags) {
synchronized (this) {
super.setErrorFlags(errorFlags);
}
}
public void __pushSilent(){
silentFlags.get().push(getErrorFlags());
setErrorFlags(0);
}
public void __popSilent(){
Integer flags = silentFlags.get().pop();
setErrorFlags(flags);
}
public void __clearSilent(){
Stack<Integer> silents = silentFlags.get();
Integer flags = null;
while (!silents.empty())
flags = silents.pop();
if (flags != null) {
setErrorFlags(flags);
}
}
@Override
public void __defineFunction(TraceInfo trace, String moduleIndex, int index) {
synchronized (this) {
super.__defineFunction(trace, moduleIndex, index);
}
}
@Override
public void registerModule(ModuleEntity module) {
synchronized (this) {
super.registerModule(module, true);
}
}
@Override
public ModuleEntity importCompiledModule(Context context, boolean debugInformation) throws Throwable {
synchronized (this) {
return super.importCompiledModule(context, debugInformation);
}
}
@Override
public ModuleEntity importModule(Context context) throws Throwable {
synchronized (this) {
return super.importModule(context);
}
}
@Override
public void registerAutoloader(SplClassLoader classLoader, boolean prepend) {
synchronized (classLoaders){
super.registerAutoloader(classLoader, prepend);
}
}
@Override
public boolean unRegisterAutoloader(SplClassLoader classLoader) {
synchronized (classLoaders){
return super.unRegisterAutoloader(classLoader);
}
}
@Override
public Memory getOrCreateGlobal(String name) {
synchronized (this.globals) {
return super.getOrCreateGlobal(name);
}
}
@Override
public Memory getOrCreateStatic(String name, Memory initValue) {
synchronized (this.statics) {
return super.getOrCreateStatic(name, initValue);
}
}
@Override
public void echo(byte[] bytes, int length) {
synchronized (this) {
super.echo(bytes, length);
}
}
@Override
public void echo(Memory value) {
synchronized (this) {
super.echo(value);
}
}
@Override
public void echo(String value) {
synchronized (this) {
super.echo(value);
}
}
@Override
public void flushAll() throws Throwable {
synchronized (this) {
super.flushAll();
}
}
}