From 022ef4c06ba0da210f3a34dde3d3610c00940441 Mon Sep 17 00:00:00 2001 From: Neil GM Richards Date: Sat, 26 Mar 2016 22:00:27 +0000 Subject: [PATCH] Better encapsulate singleton TypeRepository, ValueHandlerImpl --- .../rmi/impl/PortableRemoteObjectImpl.java | 2 +- .../org/apache/yoko/rmi/impl/RMIServant.java | 2 +- .../org/apache/yoko/rmi/impl/RMIState.java | 23 +----------- .../org/apache/yoko/rmi/impl/RMIStub.java | 2 +- .../org/apache/yoko/rmi/impl/StubBuilder.java | 2 +- .../apache/yoko/rmi/impl/TypeRepository.java | 24 +++++++++--- .../org/apache/yoko/rmi/impl/UtilImpl.java | 7 ++-- .../yoko/rmi/impl/ValueHandlerImpl.java | 37 +++++++++++++------ 8 files changed, 52 insertions(+), 47 deletions(-) diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/PortableRemoteObjectImpl.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/PortableRemoteObjectImpl.java index e7ae51d5..c3815b2a 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/PortableRemoteObjectImpl.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/PortableRemoteObjectImpl.java @@ -298,7 +298,7 @@ static Constructor getRMIStubClassConstructor(RMIState state, Cl return cons; } - TypeRepository repository = state.getTypeRepository(); + TypeRepository repository = state.repo; RemoteDescriptor desc = (RemoteDescriptor) repository.getRemoteInterface(type); MethodDescriptor[] mdesc = desc.getMethods(); diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIServant.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIServant.java index 7653afdc..e18b395e 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIServant.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIServant.java @@ -178,7 +178,7 @@ public synchronized void setTarget(java.rmi.Remote target) { throw new IllegalArgumentException(); } - _descriptor = _state.getTypeRepository().getRemoteInterface(target.getClass()).getRemoteInterface(); + _descriptor = _state.repo.getRemoteInterface(target.getClass()).getRemoteInterface(); if (_descriptor == null) { throw new RuntimeException("remote classes not supported"); diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIState.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIState.java index 0693d5f3..e6f22820 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIState.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIState.java @@ -51,7 +51,7 @@ public class RMIState implements PortableRemoteObjectState { private String _name; - private TypeRepository _typerepository; + final TypeRepository repo = TypeRepository.get(); private POA poa; @@ -59,13 +59,6 @@ POA getPOA() { return poa; } - TypeRepository getTypeRepository() { - if (_typerepository == null) - _typerepository = new TypeRepository(_orb); - - return _typerepository; - } - RMIState(org.omg.CORBA.ORB orb, String name) { if (orb == null) { throw new NullPointerException("ORB is null"); @@ -133,18 +126,6 @@ org.omg.CORBA.portable.Delegate createDelegate(RMIServant servant) { return ref._get_delegate(); } - ValueHandler valueHandler; - - public ValueHandler createValueHandler() { - checkShutDown(); - - if (valueHandler == null) { - valueHandler = new ValueHandlerImpl(getTypeRepository()); - } - - return valueHandler; - } - static RMIState current() { return (RMIState) PortableRemoteObjectExt.getState(); } @@ -190,8 +171,6 @@ public URL getCodeBase() { } void clearState() { - _typerepository = null; - valueHandler = null; stub_map = null; tie_map = null; diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIStub.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIStub.java index db41e66f..98f61a02 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIStub.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/RMIStub.java @@ -39,7 +39,7 @@ public RMIStub() { Class remote_interface = getClass().getInterfaces()[0]; RMIState state = (RMIState) PortableRemoteObjectExt.getState(); - Object o = state.getTypeRepository().getRemoteInterface( + Object o = state.repo.getRemoteInterface( remote_interface); _descriptor = (RemoteDescriptor) o; diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/StubBuilder.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/StubBuilder.java index ad85fcc6..8fc509d2 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/StubBuilder.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/StubBuilder.java @@ -45,7 +45,7 @@ static public Collection generateStubs(File dir, Collection interfaces) Set pending = new HashSet(); ArrayList result = new ArrayList(); - TypeRepository rep = new TypeRepository(null); + TypeRepository rep = TypeRepository.get(); Iterator it = interfaces.iterator(); while (it.hasNext()) { Class cl = (Class) it.next(); diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java index 1ba46116..31c2d4fc 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/TypeRepository.java @@ -34,6 +34,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; @@ -54,8 +55,6 @@ public class TypeRepository { static final Logger logger = Logger.getLogger(TypeRepository.class.getName()); - org.omg.CORBA.ORB orb; - private static final class TypeDescriptorCache { private final ConcurrentMap, WeakReference> map = new ConcurrentHashMap<>(); @@ -249,8 +248,7 @@ private static Set> createClassSet(Class...types) { return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(types))); } - public TypeRepository(org.omg.CORBA.ORB orb) { - this.orb = orb; + private TypeRepository() { repIdDescriptors = new TypeDescriptorCache(); localDescriptors = new LocalDescriptors(this, repIdDescriptors); @@ -259,8 +257,22 @@ public TypeRepository(org.omg.CORBA.ORB orb) { } } - org.omg.CORBA.ORB getORB() { - return orb; + private static final AtomicReference> singletonWeakRef = new AtomicReference<>(); + public static TypeRepository get() { + TypeRepository repo = null; + WeakReference weakRef = singletonWeakRef.get(); + if (null != weakRef) { + repo = weakRef.get(); + if (null != repo) return repo; + } + final TypeRepository newRepo = new TypeRepository(); + final WeakReference newRef = new WeakReference<>(newRepo); + while(!!!singletonWeakRef.compareAndSet(weakRef, newRef)) { + weakRef = singletonWeakRef.get(); + repo = weakRef.get(); + if (null != repo) return repo; + } + return newRepo; } public String getRepositoryID(Class type) { diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/UtilImpl.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/UtilImpl.java index 8fe5335e..d7f2ab09 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/UtilImpl.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/UtilImpl.java @@ -467,8 +467,7 @@ public Tie getTie(Remote obj) { } public ValueHandler createValueHandler() { - return RMIState.current().createValueHandler(); - // return new ValueHandlerImpl (null); + return ValueHandlerImpl.get(); } public String getCodebase(@SuppressWarnings("rawtypes") Class clz) { @@ -775,7 +774,7 @@ public Object copyObject(Object obj, org.omg.CORBA.ORB orb) * mapSystemException (ex); } */ try { - TypeRepository rep = RMIState.current().getTypeRepository(); + TypeRepository rep = RMIState.current().repo; CopyState state = new CopyState(rep); return state.copy(obj); } catch (CopyRecursionException ex) { @@ -806,7 +805,7 @@ public Object[] copyObjects(Object[] objs, org.omg.CORBA.ORB orb) try { - TypeRepository rep = RMIState.current().getTypeRepository(); + TypeRepository rep = RMIState.current().repo; CopyState state = new CopyState(rep); try { return (Object[]) state.copy(objs); diff --git a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueHandlerImpl.java b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueHandlerImpl.java index 6bfb65aa..0ed86c0f 100755 --- a/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueHandlerImpl.java +++ b/yoko-rmi-impl/src/main/java/org/apache/yoko/rmi/impl/ValueHandlerImpl.java @@ -18,6 +18,8 @@ package org.apache.yoko.rmi.impl; +import java.lang.ref.WeakReference; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,30 +35,43 @@ public class ValueHandlerImpl implements ValueHandler { static final Logger logger = Logger.getLogger(ValueHandlerImpl.class .getName()); - TypeRepository repository; + private final TypeRepository repo; RunTimeCodeBaseImpl codeBase; - private TypeRepository getRepository() { - return RMIState.current().getTypeRepository(); // repository; + private ValueHandlerImpl() { + this.repo = TypeRepository.get(); } - ValueHandlerImpl(TypeRepository rep) { - this.repository = rep; + private static final AtomicReference> singletonWeakRef = new AtomicReference<>(); + public static ValueHandlerImpl get() { + ValueHandlerImpl vh = null; + WeakReference weakRef = singletonWeakRef.get(); + if (null != weakRef) { + vh = weakRef.get(); + if (null != vh) return vh; + } + final ValueHandlerImpl newVh = new ValueHandlerImpl(); + final WeakReference newRef = new WeakReference<>(newVh); + while(!!!singletonWeakRef.compareAndSet(weakRef, newRef)) { + weakRef = singletonWeakRef.get(); + vh = weakRef.get(); + if (null != vh) return vh; + } + return newVh; } private ValueDescriptor desc(Class clz) { - return (ValueDescriptor) getRepository().getDescriptor(clz); + return (ValueDescriptor) repo.getDescriptor(clz); } private ValueDescriptor desc(String repId) { - return (ValueDescriptor)getRepository().getDescriptor(repId); + return (ValueDescriptor) repo.getDescriptor(repId); } private ValueDescriptor desc(Class clz, String repid, RunTime runtime) { try { - return (ValueDescriptor) getRepository().getDescriptor(clz, repid, - runtime); + return repo.getDescriptor(clz, repid, runtime); } catch (ClassNotFoundException ex) { MARSHAL m = new MARSHAL("class not found " + ex.getMessage()); m.initCause(ex); @@ -127,7 +142,7 @@ public java.io.Serializable readValue0( } public java.lang.String getRMIRepositoryID(java.lang.Class clz) { - return getRepository().getDescriptor(clz).getRepositoryID(); + return repo.getDescriptor(clz).getRepositoryID(); } @Override @@ -331,7 +346,7 @@ String[] getBases(String id) { } private void addIfRMIClass(java.util.List list, Class clz) { - TypeDescriptor desc = getRepository().getDescriptor(clz); + TypeDescriptor desc = repo.getDescriptor(clz); if (desc instanceof RemoteDescriptor) list.add(desc);