- /*
- * @(#)POAImpl.java 1.138 04/03/01
- *
- * Copyright 2004 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 ;
-
- // Note that we do not synchronize on this, since this is
- // the PerformDestroy instance, not the POA.
- try {
- poa.lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling performDestroy on poa " + poa ) ;
- }
-
- if (poa.state <= STATE_RUN) {
- poa.state = STATE_DESTROYING ;
- } else {
- // destroy may be called multiple times, and each call
- // is allowed to proceed with its own setting of the wait
- // flag, but the etherealize value is used from the first
- // call to destroy. Also all children should be destroyed
- // before the parent POA. If the poa is already destroyed,
- // we can just return. If the poa has started destruction,
- // but not completed, and wait is true, we need to wait
- // until destruction is complete, then just return.
- if (wait)
- while (poa.state != STATE_DESTROYED) {
- try {
- poa.beingDestroyedCV.await() ;
- } catch (InterruptedException exc) {
- // NO-OP
- }
- }
-
- return false ;
- }
-
- poa.isDestroying.set(Boolean.TRUE);
-
- // Make a copy since we can't hold the lock while destroying
- // the children, and an iterator is not deletion-safe.
- childPoas = (POAImpl[])poa.children.values().toArray(
- new POAImpl[0] );
- } finally {
- poa.unlock() ;
- }
-
- // We are not holding the POA mutex here to avoid holding it
- // while destroying the POA's children, since this may involve
- // upcalls to etherealize methods.
-
- for (int ctr=0; ctr<childPoas.length; ctr++ ) {
- performDestroy( childPoas[ctr], destroyedPOATemplates ) ;
- }
-
- return true ;
- }
-
- public void performDestroy( POAImpl poa, Set destroyedPOATemplates )
- {
- if (!prepareForDestruction( poa, destroyedPOATemplates ))
- return ;
-
- // NOTE: If we are here, poa is in STATE_DESTROYING state. All
- // other state checks are taken care of in prepareForDestruction.
- // No other threads may either be starting new invocations
- // by calling enter or starting to destroy poa. There may
- // still be pending invocations.
-
- POAImpl parent = poa.parent ;
- boolean isRoot = parent == null ;
-
- try {
- // Note that we must lock the parent before the child.
- // The parent lock is required (if poa is not the root)
- // to safely remove poa from parent's children Map.
- if (!isRoot)
- parent.lock() ;
-
- try {
- poa.lock() ;
-
- completeDestruction( poa, parent,
- destroyedPOATemplates ) ;
- } finally {
- poa.unlock() ;
-
- if (isRoot)
- // We have just destroyed the root POA, so we need to
- // make sure that the next call to
- // resolve_initial_reference( "RootPOA" )
- // will recreate a valid root POA.
- poa.manager.getFactory().registerRootPOA() ;
- }
- } finally {
- if (!isRoot) {
- parent.unlock() ;
- poa.parent = null ;
- }
- }
- }
-
- private void completeDestruction( POAImpl poa, POAImpl parent,
- Set destroyedPOATemplates )
- {
- if (debug) {
- ORBUtility.dprint( this,
- "Calling completeDestruction on poa " + poa ) ;
- }
-
- try {
- while (poa.invocationCount != 0) {
- try {
- poa.invokeCV.await() ;
- } catch (InterruptedException ex) {
- // NO-OP
- }
- }
-
- if (poa.mediator != null) {
- if (etherealize)
- poa.mediator.etherealizeAll();
-
- poa.mediator.clearAOM() ;
- }
-
- if (poa.manager != null)
- poa.manager.removePOA(poa);
-
- if (parent != null)
- parent.children.remove( poa.name ) ;
-
- destroyedPOATemplates.add( poa.getAdapterTemplate() ) ;
- } catch (Throwable thr) {
- if (thr instanceof ThreadDeath)
- throw (ThreadDeath)thr ;
-
- poa.lifecycleWrapper().unexpectedException( thr, poa.toString() ) ;
- } finally {
- poa.state = STATE_DESTROYED ;
- poa.beingDestroyedCV.broadcast();
- poa.isDestroying.set(Boolean.FALSE);
-
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting completeDestruction on poa " + poa ) ;
- }
- }
- }
- }
-
- void etherealizeAll()
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling etheralizeAll on poa " + this ) ;
- }
-
- mediator.etherealizeAll() ;
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting etheralizeAll on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
-
- //*******************************************************************
- // Public POA API
- //*******************************************************************
-
- /**
- * <code>create_POA</code>
- * <b>Section 3.3.8.2</b>
- */
- public POA create_POA(String name, POAManager
- theManager, Policy[] policies) throws AdapterAlreadyExists,
- InvalidPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling create_POA(name=" + name +
- " theManager=" + theManager + " policies=" + policies +
- ") on poa " + this ) ;
- }
-
- // We cannot create children of a POA that is (being) destroyed.
- // This has been added to the CORBA 3.0 spec.
- if (state > STATE_RUN)
- throw omgLifecycleWrapper().createPoaDestroy() ;
-
- POAImpl poa = (POAImpl)(children.get(name)) ;
-
- if (poa == null) {
- poa = new POAImpl( name, this, getORB(), STATE_START ) ;
- }
-
- try {
- poa.lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling create_POA: new poa is " + poa ) ;
- }
-
- if ((poa.state != STATE_START) && (poa.state != STATE_INIT))
- throw new AdapterAlreadyExists();
-
- POAManagerImpl newManager = (POAManagerImpl)theManager ;
- if (newManager == null)
- newManager = new POAManagerImpl( manager.getFactory(),
- manager.getPIHandler() );
-
- int defaultCopierId =
- getORB().getCopierManager().getDefaultId() ;
- Policies POAPolicies =
- new Policies( policies, defaultCopierId ) ;
-
- poa.initialize( newManager, POAPolicies ) ;
-
- return poa;
- } finally {
- poa.unlock() ;
- }
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>find_POA</code>
- * <b>Section 3.3.8.3</b>
- */
- public POA find_POA(String name, boolean activate)
- throws AdapterNonExistent
- {
- POAImpl found = null ;
- AdapterActivator act = null ;
-
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling find_POA(name=" + name +
- " activate=" + activate + ") on poa " + this ) ;
- }
-
- found = (POAImpl) children.get(name);
-
- if (found != null) {
- if (debug) {
- ORBUtility.dprint( this,
- "Calling find_POA: found poa " + found ) ;
- }
-
- try {
- found.lock() ;
-
- // Do not hold the parent POA lock while
- // waiting for child to complete initialization.
- unlock() ;
-
- // Make sure that the child has completed its initialization,
- // if it was created by an AdapterActivator, otherwise throw
- // a standard TRANSIENT exception with minor code 4 (see
- // CORBA 3.0 11.3.9.3, in reference to unknown_adapter)
- if (!found.waitUntilRunning())
- throw omgLifecycleWrapper().poaDestroyed() ;
-
- // Note that found may be in state DESTROYING or DESTROYED at
- // this point. That's OK, since destruction could start at
- // any time.
- } finally {
- found.unlock() ;
- }
- } else {
- try {
- if (debug) {
- ORBUtility.dprint( this,
- "Calling find_POA: no poa found" ) ;
- }
-
- if (activate && (activator != null)) {
- // Create a child, but don't initialize it. The newly
- // created POA will be in state STATE_START, which will
- // cause other calls to find_POA that are creating the same
- // POA to block on the waitUntilRunning call above.
- // Initialization must be completed by a call to create_POA
- // inside the unknown_adapter upcall. Note that
- // this.poaMutex must be held here so that this.children
- // can be safely updated. The state is set to STATE_INIT
- // so that initialize can make the correct state transition
- // when create_POA is called inside the AdapterActivator.
- // This avoids activating the new POA too soon
- // by transitioning to STATE_RUN after unknown_adapter
- // returns.
- found = new POAImpl( name, this, getORB(), STATE_INIT ) ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling find_POA: created poa " + found ) ;
- }
-
- act = activator ;
- } else {
- throw new AdapterNonExistent();
- }
- } finally {
- unlock() ;
- }
- }
-
- // assert (found != null)
- // assert not holding this.poaMutex OR found.poaMutex
-
- // We must not hold either this.poaMutex or found.poaMutex here while
- // waiting for intialization of found to complete to prevent possible
- // deadlocks.
-
- if (act != null) {
- boolean status = false ;
- boolean adapterResult = false ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling find_POA: calling AdapterActivator" ) ;
- }
-
- try {
- // Prevent more than one thread at a time from executing in act
- // in case act is shared between multiple POAs.
- synchronized (act) {
- status = act.unknown_adapter(this, name);
- }
- } catch (SystemException exc) {
- throw omgLifecycleWrapper().adapterActivatorException( exc,
- name, poaId.toString() ) ;
- } catch (Throwable thr) {
- // ignore most non-system exceptions, but log them for
- // diagnostic purposes.
- lifecycleWrapper().unexpectedException( thr, this.toString() ) ;
-
- if (thr instanceof ThreadDeath)
- throw (ThreadDeath)thr ;
- } finally {
- // At this point, we have completed adapter activation.
- // Whether this was successful or not, we must call
- // destroyIfNotInitDone so that calls to enter() and create_POA()
- // that are waiting can execute again. Failing to do this
- // will cause the system to hang in complex tests.
- adapterResult = found.destroyIfNotInitDone() ;
- }
-
- if (status) {
- if (!adapterResult)
- throw omgLifecycleWrapper().adapterActivatorException( name,
- poaId.toString() ) ;
- } else {
- if (debug) {
- ORBUtility.dprint( this,
- "Calling find_POA: AdapterActivator returned false" ) ;
- }
-
- // OMG Issue 3740 is resolved to throw AdapterNonExistent if
- // unknown_adapter() returns false.
- throw new AdapterNonExistent();
- }
- }
-
- return found;
- }
-
- /**
- * <code>destroy</code>
- * <b>Section 3.3.8.4</b>
- */
- public void destroy(boolean etherealize, boolean wait_for_completion)
- {
- // This is to avoid deadlock
- if (wait_for_completion && getORB().isDuringDispatch()) {
- throw lifecycleWrapper().destroyDeadlock() ;
- }
-
- DestroyThread destroyer = new DestroyThread( etherealize, debug );
- destroyer.doIt( this, wait_for_completion ) ;
- }
-
- /**
- * <code>create_thread_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public ThreadPolicy create_thread_policy(
- ThreadPolicyValue value)
- {
- return new ThreadPolicyImpl(value);
- }
-
- /**
- * <code>create_lifespan_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public LifespanPolicy create_lifespan_policy(
- LifespanPolicyValue value)
- {
- return new LifespanPolicyImpl(value);
- }
-
- /**
- * <code>create_id_uniqueness_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public IdUniquenessPolicy create_id_uniqueness_policy(
- IdUniquenessPolicyValue value)
- {
- return new IdUniquenessPolicyImpl(value);
- }
-
- /**
- * <code>create_id_assignment_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public IdAssignmentPolicy create_id_assignment_policy(
- IdAssignmentPolicyValue value)
- {
- return new IdAssignmentPolicyImpl(value);
- }
-
- /**
- * <code>create_implicit_activation_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public ImplicitActivationPolicy create_implicit_activation_policy(
- ImplicitActivationPolicyValue value)
- {
- return new ImplicitActivationPolicyImpl(value);
- }
-
- /**
- * <code>create_servant_retention_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public ServantRetentionPolicy create_servant_retention_policy(
- ServantRetentionPolicyValue value)
- {
- return new ServantRetentionPolicyImpl(value);
- }
-
- /**
- * <code>create_request_processing_policy</code>
- * <b>Section 3.3.8.5</b>
- */
- public RequestProcessingPolicy create_request_processing_policy(
- RequestProcessingPolicyValue value)
- {
- return new RequestProcessingPolicyImpl(value);
- }
-
- /**
- * <code>the_name</code>
- * <b>Section 3.3.8.6</b>
- */
- public String the_name()
- {
- try {
- lock() ;
-
- return name;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>the_parent</code>
- * <b>Section 3.3.8.7</b>
- */
- public POA the_parent()
- {
- try {
- lock() ;
-
- return parent;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>the_children</code>
- */
- public org.omg.PortableServer.POA[] the_children()
- {
- try {
- lock() ;
-
- Collection coll = children.values() ;
- int size = coll.size() ;
- POA[] result = new POA[ size ] ;
- int index = 0 ;
- Iterator iter = coll.iterator() ;
- while (iter.hasNext()) {
- POA poa = (POA)(iter.next()) ;
- result[ index++ ] = poa ;
- }
-
- return result ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>the_POAManager</code>
- * <b>Section 3.3.8.8</b>
- */
- public POAManager the_POAManager()
- {
- try {
- lock() ;
-
- return manager;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>the_activator</code>
- * <b>Section 3.3.8.9</b>
- */
- public AdapterActivator the_activator()
- {
- try {
- lock() ;
-
- return activator;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>the_activator</code>
- * <b>Section 3.3.8.9</b>
- */
- public void the_activator(AdapterActivator activator)
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling the_activator on poa " +
- this + " activator=" + activator ) ;
- }
-
- this.activator = activator;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>get_servant_manager</code>
- * <b>Section 3.3.8.10</b>
- */
- public ServantManager get_servant_manager() throws WrongPolicy
- {
- try {
- lock() ;
-
- return mediator.getServantManager() ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>set_servant_manager</code>
- * <b>Section 3.3.8.10</b>
- */
- public void set_servant_manager(ServantManager servantManager)
- throws WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling set_servant_manager on poa " +
- this + " servantManager=" + servantManager ) ;
- }
-
- mediator.setServantManager( servantManager ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>get_servant</code>
- * <b>Section 3.3.8.12</b>
- */
- public Servant get_servant() throws NoServant, WrongPolicy
- {
- try {
- lock() ;
-
- return mediator.getDefaultServant() ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>set_servant</code>
- * <b>Section 3.3.8.13</b>
- */
- public void set_servant(Servant defaultServant)
- throws WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling set_servant on poa " +
- this + " defaultServant=" + defaultServant ) ;
- }
-
- mediator.setDefaultServant( defaultServant ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>activate_object</code>
- * <b>Section 3.3.8.14</b>
- */
- public byte[] activate_object(Servant servant)
- throws ServantAlreadyActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling activate_object on poa " + this +
- " (servant=" + servant + ")" ) ;
- }
-
- // Allocate a new system-generated object-id.
- // This will throw WrongPolicy if not SYSTEM_ID
- // policy.
- byte[] id = mediator.newSystemId();
-
- try {
- mediator.activateObject( id, servant ) ;
- } catch (ObjectAlreadyActive oaa) {
- // This exception can not occur in this case,
- // since id is always brand new.
- //
- }
-
- return id ;
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting activate_object on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
-
- /**
- * <code>activate_object_with_id</code>
- * <b>Section 3.3.8.15</b>
- */
- public void activate_object_with_id(byte[] id,
- Servant servant)
- throws ObjectAlreadyActive, ServantAlreadyActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling activate_object_with_id on poa " + this +
- " (servant=" + servant + " id=" + id + ")" ) ;
- }
-
- // Clone the id to avoid possible errors due to aliasing
- // (e.g. the client passes the id in and then changes it later).
- byte[] idClone = (byte[])(id.clone()) ;
-
- mediator.activateObject( idClone, servant ) ;
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting activate_object_with_id on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
-
- /**
- * <code>deactivate_object</code>
- * <b>3.3.8.16</b>
- */
- public void deactivate_object(byte[] id)
- throws ObjectNotActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling deactivate_object on poa " + this +
- " (id=" + id + ")" ) ;
- }
-
- mediator.deactivateObject( id ) ;
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting deactivate_object on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
-
- /**
- * <code>create_reference</code>
- * <b>3.3.8.17</b>
- */
- public org.omg.CORBA.Object create_reference(String repId)
- throws WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling create_reference(repId=" +
- repId + ") on poa " + this ) ;
- }
-
- return makeObject( repId, mediator.newSystemId()) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>create_reference_with_id</code>
- * <b>3.3.8.18</b>
- */
- public org.omg.CORBA.Object
- create_reference_with_id(byte[] oid, String repId)
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling create_reference_with_id(oid=" +
- oid + " repId=" + repId + ") on poa " + this ) ;
- }
-
- // Clone the id to avoid possible errors due to aliasing
- // (e.g. the client passes the id in and then changes it later).
- byte[] idClone = (byte[])(oid.clone()) ;
-
- return makeObject( repId, idClone ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>servant_to_id</code>
- * <b>3.3.8.19</b>
- */
- public byte[] servant_to_id(Servant servant)
- throws ServantNotActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling servant_to_id(servant=" +
- servant + ") on poa " + this ) ;
- }
-
- return mediator.servantToId( servant ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>servant_to_reference</code>
- * <b>3.3.8.20</b>
- */
- public org.omg.CORBA.Object servant_to_reference(Servant servant)
- throws ServantNotActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling servant_to_reference(servant=" +
- servant + ") on poa " + this ) ;
- }
-
- byte[] oid = mediator.servantToId(servant);
- String repId = servant._all_interfaces( this, oid )[0] ;
- return create_reference_with_id(oid, repId);
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>reference_to_servant</code>
- * <b>3.3.8.21</b>
- */
- public Servant reference_to_servant(org.omg.CORBA.Object reference)
- throws ObjectNotActive, WrongPolicy, WrongAdapter
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling reference_to_servant(reference=" +
- reference + ") on poa " + this ) ;
- }
-
- if ( state >= STATE_DESTROYING ) {
- throw lifecycleWrapper().adapterDestroyed() ;
- }
-
- // reference_to_id should throw WrongAdapter
- // if the objref was not created by this POA
- byte [] id = internalReferenceToId(reference);
-
- return mediator.idToServant( id ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>reference_to_id</code>
- * <b>3.3.8.22</b>
- */
- public byte[] reference_to_id(org.omg.CORBA.Object reference)
- throws WrongAdapter, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling reference_to_id(reference=" +
- reference + ") on poa " + this ) ;
- }
-
- if( state >= STATE_DESTROYING ) {
- throw lifecycleWrapper().adapterDestroyed() ;
- }
-
- return internalReferenceToId( reference ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>id_to_servant</code>
- * <b>3.3.8.23</b>
- */
- public Servant id_to_servant(byte[] id)
- throws ObjectNotActive, WrongPolicy
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling id_to_servant(id=" +
- id + ") on poa " + this ) ;
- }
-
- if( state >= STATE_DESTROYING ) {
- throw lifecycleWrapper().adapterDestroyed() ;
- }
- return mediator.idToServant( id ) ;
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>id_to_reference</code>
- * <b>3.3.8.24</b>
- */
- public org.omg.CORBA.Object id_to_reference(byte[] id)
- throws ObjectNotActive, WrongPolicy
-
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling id_to_reference(id=" +
- id + ") on poa " + this ) ;
- }
-
- if( state >= STATE_DESTROYING ) {
- throw lifecycleWrapper().adapterDestroyed() ;
- }
-
- Servant s = mediator.idToServant( id ) ;
- String repId = s._all_interfaces( this, id )[0] ;
- return makeObject(repId, id );
- } finally {
- unlock() ;
- }
- }
-
- /**
- * <code>id</code>
- * <b>11.3.8.26 in ptc/00-08-06</b>
- */
- public byte[] id()
- {
- try {
- lock() ;
-
- return getAdapterId() ;
- } finally {
- unlock() ;
- }
- }
-
- //***************************************************************
- //Implementation of ObjectAdapter interface
- //***************************************************************
-
- public Policy getEffectivePolicy( int type )
- {
- return mediator.getPolicies().get_effective_policy( type ) ;
- }
-
- public int getManagerId()
- {
- return manager.getManagerId() ;
- }
-
- public short getState()
- {
- return manager.getORTState() ;
- }
-
- public String[] getInterfaces( java.lang.Object servant, byte[] objectId )
- {
- Servant serv = (Servant)servant ;
- return serv._all_interfaces( this, objectId ) ;
- }
-
- protected ObjectCopierFactory getObjectCopierFactory()
- {
- int copierId = mediator.getPolicies().getCopierId() ;
- CopierManager cm = getORB().getCopierManager() ;
- return cm.getObjectCopierFactory( copierId ) ;
- }
-
- public void enter() throws OADestroyed
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling enter on poa " + this ) ;
- }
-
- // Avoid deadlock if this is the thread that is processing the
- // POA.destroy because this is the only thread that can notify
- // waiters on beingDestroyedCV. This can happen if an
- // etherealize upcall invokes a method on a colocated object
- // served by this POA.
- while ((state == STATE_DESTROYING) &&
- (isDestroying.get() == Boolean.FALSE)) {
- try {
- beingDestroyedCV.await();
- } catch (InterruptedException ex) {
- // NO-OP
- }
- }
-
- if (!waitUntilRunning())
- throw new OADestroyed() ;
-
- invocationCount++;
- } finally {
- if (debug) {
- ORBUtility.dprint( this, "Exiting enter on poa " + this ) ;
- }
-
- unlock() ;
- }
-
- manager.enter();
- }
-
- public void exit()
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this, "Calling exit on poa " + this ) ;
- }
-
- invocationCount--;
-
- if ((invocationCount == 0) && (state == STATE_DESTROYING)) {
- invokeCV.broadcast();
- }
- } finally {
- if (debug) {
- ORBUtility.dprint( this, "Exiting exit on poa " + this ) ;
- }
-
- unlock() ;
- }
-
- manager.exit();
- }
-
- public void getInvocationServant( OAInvocationInfo info )
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling getInvocationServant on poa " + this ) ;
- }
-
- java.lang.Object servant = null ;
-
- try {
- servant = mediator.getInvocationServant( info.id(),
- info.getOperation() );
- } catch (ForwardRequest freq) {
- throw new ForwardException( getORB(), freq.forward_reference ) ;
- }
-
- info.setServant( servant ) ;
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting getInvocationServant on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
-
- public org.omg.CORBA.Object getLocalServant( byte[] objectId )
- {
- return null ;
- }
-
- /** Called from the subcontract to let this POA cleanup after an
- * invocation. Note: If getServant was called, then returnServant
- * MUST be called, even in the case of exceptions. This may be
- * called multiple times for a single request.
- */
- public void returnServant()
- {
- try {
- lock() ;
-
- if (debug) {
- ORBUtility.dprint( this,
- "Calling returnServant on poa " + this ) ;
- }
-
- mediator.returnServant();
- } catch (Throwable thr) {
- if (debug) {
- ORBUtility.dprint( this,
- "Exception " + thr + " in returnServant on poa " + this ) ;
- }
-
- if (thr instanceof Error)
- throw (Error)thr ;
- else if (thr instanceof RuntimeException)
- throw (RuntimeException)thr ;
-
- } finally {
- if (debug) {
- ORBUtility.dprint( this,
- "Exiting returnServant on poa " + this ) ;
- }
-
- unlock() ;
- }
- }
- }