📄 poaimpl.java
字号:
/* * @(#)POAImpl.java 1.139 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.corba.se.impl.oa.poa;import java.util.Collection ;import java.util.Set ;import java.util.HashSet ;import java.util.Map ;import java.util.HashMap ;import java.util.Iterator ;import org.omg.CORBA.Policy ;import org.omg.CORBA.SystemException ;import org.omg.PortableServer.POA ;import org.omg.PortableServer.Servant ;import org.omg.PortableServer.POAManager ;import org.omg.PortableServer.AdapterActivator ;import org.omg.PortableServer.ServantManager ;import org.omg.PortableServer.ForwardRequest ;import org.omg.PortableServer.ThreadPolicy;import org.omg.PortableServer.LifespanPolicy;import org.omg.PortableServer.IdUniquenessPolicy;import org.omg.PortableServer.IdAssignmentPolicy;import org.omg.PortableServer.ImplicitActivationPolicy;import org.omg.PortableServer.ServantRetentionPolicy;import org.omg.PortableServer.RequestProcessingPolicy;import org.omg.PortableServer.ThreadPolicyValue ;import org.omg.PortableServer.LifespanPolicyValue ;import org.omg.PortableServer.IdUniquenessPolicyValue ;import org.omg.PortableServer.IdAssignmentPolicyValue ;import org.omg.PortableServer.ImplicitActivationPolicyValue ;import org.omg.PortableServer.ServantRetentionPolicyValue ;import org.omg.PortableServer.RequestProcessingPolicyValue ;import org.omg.PortableServer.POAPackage.AdapterAlreadyExists ;import org.omg.PortableServer.POAPackage.AdapterNonExistent ;import org.omg.PortableServer.POAPackage.InvalidPolicy ;import org.omg.PortableServer.POAPackage.WrongPolicy ;import org.omg.PortableServer.POAPackage.WrongAdapter ;import org.omg.PortableServer.POAPackage.NoServant ;import org.omg.PortableServer.POAPackage.ServantAlreadyActive ;import org.omg.PortableServer.POAPackage.ObjectAlreadyActive ;import org.omg.PortableServer.POAPackage.ServantNotActive ;import org.omg.PortableServer.POAPackage.ObjectNotActive ;import org.omg.PortableInterceptor.ObjectReferenceFactory ;import org.omg.PortableInterceptor.ObjectReferenceTemplate ;import org.omg.PortableInterceptor.NON_EXISTENT ;import org.omg.IOP.TAG_INTERNET_IOP ;import com.sun.corba.se.spi.copyobject.CopierManager ;import com.sun.corba.se.spi.copyobject.ObjectCopier ;import com.sun.corba.se.spi.copyobject.ObjectCopierFactory ;import com.sun.corba.se.spi.oa.OADestroyed ;import com.sun.corba.se.spi.oa.OAInvocationInfo ;import com.sun.corba.se.spi.oa.ObjectAdapter ;import com.sun.corba.se.spi.oa.ObjectAdapterBase ;import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;import com.sun.corba.se.spi.ior.ObjectId ;import com.sun.corba.se.spi.ior.ObjectAdapterId ;import com.sun.corba.se.spi.ior.IOR ;import com.sun.corba.se.spi.ior.IORFactories ;import com.sun.corba.se.spi.ior.IORTemplate ;import com.sun.corba.se.spi.ior.IORTemplateList ;import com.sun.corba.se.spi.ior.TaggedProfile ;import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;import com.sun.corba.se.spi.orb.ORB ;import com.sun.corba.se.spi.protocol.ForwardException ;import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ;import com.sun.corba.se.impl.ior.ObjectAdapterIdArray ;import com.sun.corba.se.impl.orbutil.ORBUtility; import com.sun.corba.se.impl.orbutil.ORBConstants; import com.sun.corba.se.impl.orbutil.concurrent.Sync ; import com.sun.corba.se.impl.orbutil.concurrent.SyncUtil ; import com.sun.corba.se.impl.orbutil.concurrent.ReentrantMutex ; import com.sun.corba.se.impl.orbutil.concurrent.CondVar ; /** * POAImpl is the implementation of the Portable Object Adapter. It * contains an implementation of the POA interfaces specified in * COBRA 2.3.1 chapter 11 (formal/99-10-07). This implementation * is moving to comply with CORBA 3.0 due to the many clarifications * that have been made to the POA semantics since CORBA 2.3.1. * Specific comments have been added where 3.0 applies, but note that * we do not have the new 3.0 APIs yet. */public class POAImpl extends ObjectAdapterBase implements POA { private boolean debug ; /* POA creation takes place in 2 stages: first, the POAImpl constructor is called, then the initialize method is called. This separation is needed because an AdapterActivator does not know the POAManager or the policies when the unknown_adapter method is invoked. However, the POA must be created before the unknown_adapter method is invoked, so that the parent knows when concurrent attempts are made to create the same POA. Calling the POAImpl constructor results in a new POA in state STATE_START. Calling initialize( POAManager, Policies ) results in state STATE_RUN. Calling destroy results in STATE_DESTROY, which marks the beginning of POA destruction. */ // Notes on concurrency. // The POA requires careful design for concurrency management to correctly // implement the specification and avoid deadlocks. The order of acquiring // locks must respect the following locking hierarchy: // // 1. Lock POAs before POAManagers // 2. Lock a POA before locking its child POA // // Also note that there are 3 separate conditions on which threads may wait // in the POA, as defined by invokeCV, beingDestroyedCV, and // adapterActivatorCV. This means that (for this reason as well as others) // we cannot simply use the standard Java synchronized primitive. // This implementation uses a modified version of Doug Lea's // util.concurrent (version 1.3.0) that supports reentrant // mutexes to handle the locking. This will all be replaced by the new JSR // 166 concurrency primitives in J2SE 1.5 and later once the ORB moves to // J2SE 1.5. // POA state constants // // Note that ordering is important here: we must have the state defined in // this order so that ordered comparison is possible. // DO NOT CHANGE THE VALUES OF THE STATE CONSTANTS!!! In particular, the // initialization related states must be lower than STATE_RUN. // // POA is created in STATE_START // // Valid state transitions: // // START to INIT after find_POA constructor call // START to RUN after initialize completes // INIT to INIT_DONE after initialize completes // INIT to DESTROYED after failed unknown_adapter // INIT_DONE to RUN after successful unknown_adapter // STATE_RUN to STATE_DESTROYING after start of destruction // STATE_DESTROYING to STATE_DESTROYED after destruction completes. private static final int STATE_START = 0 ; // constructor complete private static final int STATE_INIT = 1 ; // waiting for adapter activator private static final int STATE_INIT_DONE = 2 ; // adapter activator called create_POA private static final int STATE_RUN = 3 ; // initialized and running private static final int STATE_DESTROYING = 4 ; // being destroyed private static final int STATE_DESTROYED = 5 ; // destruction complete private String stateToString() { switch (state) { case STATE_START : return "START" ; case STATE_INIT : return "INIT" ; case STATE_INIT_DONE : return "INIT_DONE" ; case STATE_RUN : return "RUN" ; case STATE_DESTROYING : return "DESTROYING" ; case STATE_DESTROYED : return "DESTROYED" ; default : return "UNKNOWN(" + state + ")" ; } } // Current state of the POA private int state ; // The POA request handler that performs all policy specific operations // Note that POAImpl handles all synchronization, so mediator is (mostly) // unsynchronized. private POAPolicyMediator mediator; // Representation of object adapter ID private int numLevels; // counts depth of tree. Root = 1. private ObjectAdapterId poaId ; // the actual object adapter ID for this POA private String name; // the name of this POA private POAManagerImpl manager; // This POA's POAManager private int uniquePOAId ; // ID for this POA that is unique relative // to the POAFactory, which has the same // lifetime as the ORB. private POAImpl parent; // The POA that created this POA. private Map children; // Map from name to POA of POAs created by // this POA. private AdapterActivator activator; private int invocationCount ; // pending invocations on this POA. // Data used to control POA concurrency // XXX revisit for JSR 166 // Master lock for all POA synchronization. See lock and unlock. // package private for access by AOMEntry. Sync poaMutex ; // Wait on this CV for AdapterActivator upcalls to complete private CondVar adapterActivatorCV ; // Wait on this CV for all active invocations to complete private CondVar invokeCV ; // Wait on this CV for the destroy method to complete doing its work private CondVar beingDestroyedCV ; // thread local variable to store a boolean to detect deadlock in // POA.destroy(). protected ThreadLocal isDestroying ; // This includes the most important information for debugging // POA problems. public String toString() { return "POA[" + poaId.toString() + ", uniquePOAId=" + uniquePOAId + ", state=" + stateToString() + ", invocationCount=" + invocationCount + "]" ; } // package private for mediator implementations. boolean getDebug() { return debug ; } // package private for access to servant to POA map static POAFactory getPOAFactory( ORB orb ) { return (POAFactory)orb.getRequestDispatcherRegistry(). getObjectAdapterFactory( ORBConstants.TRANSIENT_SCID ) ; } // package private so that POAFactory can access it. static POAImpl makeRootPOA( ORB orb ) { POAManagerImpl poaManager = new POAManagerImpl( getPOAFactory( orb ), orb.getPIHandler() ) ; POAImpl result = new POAImpl( ORBConstants.ROOT_POA_NAME, null, orb, STATE_START ) ; result.initialize( poaManager, Policies.rootPOAPolicies ) ; return result ; } // package private so that POAPolicyMediatorBase can access it. int getPOAId() { return uniquePOAId ; } // package private so that POAPolicyMediator can access it. void lock() { SyncUtil.acquire( poaMutex ) ; if (debug) { ORBUtility.dprint( this, "LOCKED poa " + this ) ; } } // package private so that POAPolicyMediator can access it. void unlock() { if (debug) { ORBUtility.dprint( this, "UNLOCKED poa " + this ) ; } poaMutex.release() ; } // package private so that DelegateImpl can access it. Policies getPolicies() { return mediator.getPolicies() ; } // Note that the parent POA must be locked when this constructor is called. private POAImpl( String name, POAImpl parent, ORB orb, int initialState ) { super( orb ) ; debug = orb.poaDebugFlag ; if (debug) { ORBUtility.dprint( this, "Creating POA with name=" + name + " parent=" + parent ) ; } this.state = initialState ; this.name = name ; this.parent = parent; children = new HashMap(); activator = null ; // This was done in initialize, but I moved it here // to get better searchability when tracing. uniquePOAId = getPOAFactory( orb ).newPOAId() ; if (parent == null) { // This is the root POA, which counts as 1 level numLevels = 1 ; } else { // My level is one more than that of my parent numLevels = parent.numLevels + 1 ; parent.children.put(name, this); } // Get an array of all of the POA names in order to // create the poaid. String[] names = new String[ numLevels ] ; POAImpl poaImpl = this ; int ctr = numLevels - 1 ; while (poaImpl != null) { names[ctr--] = poaImpl.name ; poaImpl = poaImpl.parent ; } poaId = new ObjectAdapterIdArray( names ) ; invocationCount = 0; poaMutex = new ReentrantMutex( orb.poaConcurrencyDebugFlag ) ; adapterActivatorCV = new CondVar( poaMutex, orb.poaConcurrencyDebugFlag ) ; invokeCV = new CondVar( poaMutex, orb.poaConcurrencyDebugFlag ) ; beingDestroyedCV = new CondVar( poaMutex, orb.poaConcurrencyDebugFlag ) ; isDestroying = new ThreadLocal () { protected java.lang.Object initialValue() { return Boolean.FALSE; } }; } // The POA lock must be held when this method is called. private void initialize( POAManagerImpl manager, Policies policies ) { if (debug) { ORBUtility.dprint( this, "Initializing poa " + this + " with POAManager=" + manager + " policies=" + policies ) ; } this.manager = manager; manager.addPOA(this); mediator = POAPolicyMediatorFactory.create( policies, this ) ; // Construct the object key template int serverid = mediator.getServerId() ; int scid = mediator.getScid() ; String orbId = getORB().getORBData().getORBId(); ObjectKeyTemplate oktemp = new POAObjectKeyTemplate( getORB(), scid, serverid, orbId, poaId ) ; if (debug) { ORBUtility.dprint( this, "Initializing poa: oktemp=" + oktemp ) ; } // Note that parent == null iff this is the root POA. // This was used to avoid executing interceptors on the RootPOA. // That is no longer necessary. boolean objectAdapterCreated = true; // parent != null ; // XXX extract codebase from policies and pass into initializeTemplate // after the codebase policy change is finalized. initializeTemplate( oktemp, objectAdapterCreated, policies, null, // codebase null, // manager id oktemp.getObjectAdapterId() ) ; if (state == STATE_START) state = STATE_RUN ; else if (state == STATE_INIT) state = STATE_INIT_DONE ; else throw lifecycleWrapper().illegalPoaStateTrans() ; } // The poaMutex must be held when this method is called private boolean waitUntilRunning() { if (debug) { ORBUtility.dprint( this, "Calling waitUntilRunning on poa " + this ) ; } while (state < STATE_RUN) { try { adapterActivatorCV.await() ; } catch (InterruptedException exc) { // NO-OP } } if (debug) { ORBUtility.dprint( this, "Exiting waitUntilRunning on poa " + this ) ; } // Note that a POA could be destroyed while in STATE_INIT due to a // failure in the AdapterActivator upcall. return (state == STATE_RUN) ; } // This method checks that the AdapterActivator finished the // initialization of a POA activated in find_POA. This is // determined by checking the state of the POA. If the state is // STATE_INIT, the AdapterActivator did not complete the // inialization. In this case, we destroy the POA that was // partially created and return false. Otherwise, we return true. // In any case, we must wake up all threads waiting for the adapter // activator, either to continue their invocations, or to return // errors to their client. // // The poaMutex must NOT be held when this method is called. private boolean destroyIfNotInitDone() { try { lock() ; if (debug) { ORBUtility.dprint( this, "Calling destroyIfNotInitDone on poa " + this ) ; } boolean success = (state == STATE_INIT_DONE) ; if (success) state = STATE_RUN ; else { // Don't just use destroy, because the check for // deadlock is too general, and can prevent this from // functioning properly. DestroyThread destroyer = new DestroyThread( false, debug ); destroyer.doIt( this, true ) ; } return success ; } finally { adapterActivatorCV.broadcast() ; if (debug) { ORBUtility.dprint( this, "Exiting destroyIfNotInitDone on poa " + this ) ; } unlock() ; } } private byte[] internalReferenceToId( org.omg.CORBA.Object reference ) throws WrongAdapter { IOR ior = ORBUtility.getIOR( reference ) ; IORTemplateList thisTemplate = ior.getIORTemplates() ; ObjectReferenceFactory orf = getCurrentFactory() ; IORTemplateList poaTemplate = IORFactories.getIORTemplateList( orf ) ; if (!poaTemplate.isEquivalent( thisTemplate )) throw new WrongAdapter(); // Extract the ObjectId from the first TaggedProfile in the IOR. // If ior was created in this POA, the same ID was used for // every profile through the profile templates in the currentFactory, // so we will get the same result from any profile. Iterator iter = ior.iterator() ; if (!iter.hasNext()) throw iorWrapper().noProfilesInIor() ; TaggedProfile prof = (TaggedProfile)(iter.next()) ; ObjectId oid = prof.getObjectId() ; return oid.getId(); } // Converted from anonymous class to local class // so that we can call performDestroy() directly. static class DestroyThread extends Thread { private boolean wait ; private boolean etherealize ; private boolean debug ; private POAImpl thePoa ; public DestroyThread( boolean etherealize, boolean debug ) { this.etherealize = etherealize ; this.debug = debug ; } public void doIt( POAImpl thePoa, boolean wait ) { if (debug) { ORBUtility.dprint( this, "Calling DestroyThread.doIt(thePOA=" + thePoa + " wait=" + wait + " etherealize=" + etherealize ) ; } this.thePoa = thePoa ; this.wait = wait ; if (wait) { run() ; } else { // Catch exceptions since setDaemon can cause a // security exception to be thrown under netscape // in the Applet mode try { setDaemon(true); } catch (Exception e) {} start() ; } } public void run() { Set destroyedPOATemplates = new HashSet() ; performDestroy( thePoa, destroyedPOATemplates ); Iterator iter = destroyedPOATemplates.iterator() ; ObjectReferenceTemplate[] orts = new ObjectReferenceTemplate[ destroyedPOATemplates.size() ] ; int index = 0 ; while (iter.hasNext()) orts[ index++ ] = (ObjectReferenceTemplate)iter.next(); thePoa.getORB().getPIHandler().adapterStateChanged( orts, NON_EXISTENT.value ) ; } // Returns true if destruction must be completed, false // if not, which means that another thread is already // destroying poa. private boolean prepareForDestruction( POAImpl poa, Set destroyedPOATemplates ) { POAImpl[] childPoas = null ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -