corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java
changeset 25862 a5e25d68f971
parent 5555 b2b5ed3f0d0d
child 29937 c774371adf92
equal deleted inserted replaced
25861:cca845a10cc5 25862:a5e25d68f971
       
     1 /*
       
     2  * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.corba.se.impl.oa.poa;
       
    27 
       
    28 import java.util.Collection ;
       
    29 import java.util.Set ;
       
    30 import java.util.HashSet ;
       
    31 import java.util.Map ;
       
    32 import java.util.HashMap ;
       
    33 import java.util.Iterator ;
       
    34 
       
    35 import org.omg.CORBA.Policy ;
       
    36 import org.omg.CORBA.SystemException ;
       
    37 
       
    38 import org.omg.PortableServer.POA ;
       
    39 import org.omg.PortableServer.Servant ;
       
    40 import org.omg.PortableServer.POAManager ;
       
    41 import org.omg.PortableServer.AdapterActivator ;
       
    42 import org.omg.PortableServer.ServantManager ;
       
    43 import org.omg.PortableServer.ForwardRequest ;
       
    44 import org.omg.PortableServer.ThreadPolicy;
       
    45 import org.omg.PortableServer.LifespanPolicy;
       
    46 import org.omg.PortableServer.IdUniquenessPolicy;
       
    47 import org.omg.PortableServer.IdAssignmentPolicy;
       
    48 import org.omg.PortableServer.ImplicitActivationPolicy;
       
    49 import org.omg.PortableServer.ServantRetentionPolicy;
       
    50 import org.omg.PortableServer.RequestProcessingPolicy;
       
    51 import org.omg.PortableServer.ThreadPolicyValue ;
       
    52 import org.omg.PortableServer.LifespanPolicyValue ;
       
    53 import org.omg.PortableServer.IdUniquenessPolicyValue ;
       
    54 import org.omg.PortableServer.IdAssignmentPolicyValue ;
       
    55 import org.omg.PortableServer.ImplicitActivationPolicyValue ;
       
    56 import org.omg.PortableServer.ServantRetentionPolicyValue ;
       
    57 import org.omg.PortableServer.RequestProcessingPolicyValue ;
       
    58 import org.omg.PortableServer.POAPackage.AdapterAlreadyExists ;
       
    59 import org.omg.PortableServer.POAPackage.AdapterNonExistent ;
       
    60 import org.omg.PortableServer.POAPackage.InvalidPolicy ;
       
    61 import org.omg.PortableServer.POAPackage.WrongPolicy ;
       
    62 import org.omg.PortableServer.POAPackage.WrongAdapter ;
       
    63 import org.omg.PortableServer.POAPackage.NoServant ;
       
    64 import org.omg.PortableServer.POAPackage.ServantAlreadyActive ;
       
    65 import org.omg.PortableServer.POAPackage.ObjectAlreadyActive ;
       
    66 import org.omg.PortableServer.POAPackage.ServantNotActive ;
       
    67 import org.omg.PortableServer.POAPackage.ObjectNotActive ;
       
    68 
       
    69 import org.omg.PortableInterceptor.ObjectReferenceFactory ;
       
    70 import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
       
    71 import org.omg.PortableInterceptor.NON_EXISTENT ;
       
    72 
       
    73 import org.omg.IOP.TAG_INTERNET_IOP ;
       
    74 
       
    75 import com.sun.corba.se.spi.copyobject.CopierManager ;
       
    76 import com.sun.corba.se.spi.copyobject.ObjectCopier ;
       
    77 import com.sun.corba.se.spi.copyobject.ObjectCopierFactory ;
       
    78 import com.sun.corba.se.spi.oa.OADestroyed ;
       
    79 import com.sun.corba.se.spi.oa.OAInvocationInfo ;
       
    80 import com.sun.corba.se.spi.oa.ObjectAdapter ;
       
    81 import com.sun.corba.se.spi.oa.ObjectAdapterBase ;
       
    82 import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;
       
    83 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
       
    84 import com.sun.corba.se.spi.ior.ObjectId ;
       
    85 import com.sun.corba.se.spi.ior.ObjectAdapterId ;
       
    86 import com.sun.corba.se.spi.ior.IOR ;
       
    87 import com.sun.corba.se.spi.ior.IORFactories ;
       
    88 import com.sun.corba.se.spi.ior.IORTemplate ;
       
    89 import com.sun.corba.se.spi.ior.IORTemplateList ;
       
    90 import com.sun.corba.se.spi.ior.TaggedProfile ;
       
    91 import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
       
    92 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
       
    93 import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
       
    94 import com.sun.corba.se.spi.orb.ORB ;
       
    95 import com.sun.corba.se.spi.protocol.ForwardException ;
       
    96 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
       
    97 
       
    98 import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ;
       
    99 import com.sun.corba.se.impl.ior.ObjectAdapterIdArray ;
       
   100 import com.sun.corba.se.impl.orbutil.ORBUtility;
       
   101 import com.sun.corba.se.impl.orbutil.ORBConstants;
       
   102 import com.sun.corba.se.impl.orbutil.concurrent.Sync ;
       
   103 import com.sun.corba.se.impl.orbutil.concurrent.SyncUtil ;
       
   104 import com.sun.corba.se.impl.orbutil.concurrent.ReentrantMutex ;
       
   105 import com.sun.corba.se.impl.orbutil.concurrent.CondVar ;
       
   106 
       
   107 /**
       
   108  * POAImpl is the implementation of the Portable Object Adapter. It
       
   109  * contains an implementation of the POA interfaces specified in
       
   110  * COBRA 2.3.1 chapter 11 (formal/99-10-07).  This implementation
       
   111  * is moving to comply with CORBA 3.0 due to the many clarifications
       
   112  * that have been made to the POA semantics since CORBA 2.3.1.
       
   113  * Specific comments have been added where 3.0 applies, but note that
       
   114  * we do not have the new 3.0 APIs yet.
       
   115  */
       
   116 public class POAImpl extends ObjectAdapterBase implements POA
       
   117 {
       
   118     private boolean debug ;
       
   119 
       
   120     /* POA creation takes place in 2 stages: first, the POAImpl constructor is
       
   121        called, then the initialize method is called.  This separation is
       
   122        needed because an AdapterActivator does not know the POAManager or
       
   123        the policies when
       
   124        the unknown_adapter method is invoked.  However, the POA must be created
       
   125        before the unknown_adapter method is invoked, so that the parent knows
       
   126        when concurrent attempts are made to create the same POA.
       
   127        Calling the POAImpl constructor results in a new POA in state STATE_START.
       
   128        Calling initialize( POAManager, Policies ) results in state STATE_RUN.
       
   129        Calling destroy results in STATE_DESTROY, which marks the beginning of
       
   130        POA destruction.
       
   131     */
       
   132 
       
   133     // Notes on concurrency.
       
   134     // The POA requires careful design for concurrency management to correctly
       
   135     // implement the specification and avoid deadlocks.  The order of acquiring
       
   136     // locks must respect the following locking hierarchy:
       
   137     //
       
   138     // 1. Lock POAs before POAManagers
       
   139     // 2. Lock a POA before locking its child POA
       
   140     //
       
   141     // Also note that there are 3 separate conditions on which threads may wait
       
   142     // in the POA, as defined by invokeCV, beingDestroyedCV, and
       
   143     // adapterActivatorCV.  This means that (for this reason as well as others)
       
   144     // we cannot simply use the standard Java synchronized primitive.
       
   145     // This implementation uses a modified version of Doug Lea's
       
   146     // util.concurrent (version 1.3.0) that supports reentrant
       
   147     // mutexes to handle the locking.  This will all be replaced by the new JSR
       
   148     // 166 concurrency primitives in J2SE 1.5 and later once the ORB moves to
       
   149     // J2SE 1.5.
       
   150 
       
   151     // POA state constants
       
   152     //
       
   153     // Note that ordering is important here: we must have the state defined in
       
   154     // this order so that ordered comparison is possible.
       
   155     // DO NOT CHANGE THE VALUES OF THE STATE CONSTANTS!!!  In particular, the
       
   156     // initialization related states must be lower than STATE_RUN.
       
   157     //
       
   158     // POA is created in STATE_START
       
   159     //
       
   160     // Valid state transitions:
       
   161     //
       
   162     // START to INIT                        after find_POA constructor call
       
   163     // START to RUN                         after initialize completes
       
   164     // INIT to INIT_DONE                    after initialize completes
       
   165     // INIT to DESTROYED                    after failed unknown_adapter
       
   166     // INIT_DONE to RUN                     after successful unknown_adapter
       
   167     // STATE_RUN to STATE_DESTROYING        after start of destruction
       
   168     // STATE_DESTROYING to STATE_DESTROYED  after destruction completes.
       
   169 
       
   170     private static final int STATE_START        = 0 ; // constructor complete
       
   171     private static final int STATE_INIT         = 1 ; // waiting for adapter activator
       
   172     private static final int STATE_INIT_DONE    = 2 ; // adapter activator called create_POA
       
   173     private static final int STATE_RUN          = 3 ; // initialized and running
       
   174     private static final int STATE_DESTROYING   = 4 ; // being destroyed
       
   175     private static final int STATE_DESTROYED    = 5 ; // destruction complete
       
   176 
       
   177     private String stateToString()
       
   178     {
       
   179         switch (state) {
       
   180             case STATE_START :
       
   181                 return "START" ;
       
   182             case STATE_INIT :
       
   183                 return "INIT" ;
       
   184             case STATE_INIT_DONE :
       
   185                 return "INIT_DONE" ;
       
   186             case STATE_RUN :
       
   187                 return "RUN" ;
       
   188             case STATE_DESTROYING :
       
   189                 return "DESTROYING" ;
       
   190             case STATE_DESTROYED :
       
   191                 return "DESTROYED" ;
       
   192             default :
       
   193                 return "UNKNOWN(" + state + ")" ;
       
   194         }
       
   195     }
       
   196 
       
   197     // Current state of the POA
       
   198     private int state ;
       
   199 
       
   200     // The POA request handler that performs all policy specific operations
       
   201     // Note that POAImpl handles all synchronization, so mediator is (mostly)
       
   202     // unsynchronized.
       
   203     private POAPolicyMediator mediator;
       
   204 
       
   205     // Representation of object adapter ID
       
   206     private int numLevels;          // counts depth of tree.  Root = 1.
       
   207     private ObjectAdapterId poaId ; // the actual object adapter ID for this POA
       
   208     private String name;            // the name of this POA
       
   209 
       
   210     private POAManagerImpl manager; // This POA's POAManager
       
   211     private int uniquePOAId ;       // ID for this POA that is unique relative
       
   212                                     // to the POAFactory, which has the same
       
   213                                     // lifetime as the ORB.
       
   214     private POAImpl parent;         // The POA that created this POA.
       
   215     private Map children;           // Map from name to POA of POAs created by
       
   216                                     // this POA.
       
   217 
       
   218     private AdapterActivator activator;
       
   219     private int invocationCount ; // pending invocations on this POA.
       
   220 
       
   221     // Data used to control POA concurrency
       
   222     // XXX revisit for JSR 166
       
   223 
       
   224     // Master lock for all POA synchronization.  See lock and unlock.
       
   225     // package private for access by AOMEntry.
       
   226     Sync poaMutex ;
       
   227 
       
   228     // Wait on this CV for AdapterActivator upcalls to complete
       
   229     private CondVar adapterActivatorCV ;
       
   230 
       
   231     // Wait on this CV for all active invocations to complete
       
   232     private CondVar invokeCV ;
       
   233 
       
   234     // Wait on this CV for the destroy method to complete doing its work
       
   235     private CondVar beingDestroyedCV ;
       
   236 
       
   237     // thread local variable to store a boolean to detect deadlock in
       
   238     // POA.destroy().
       
   239     protected ThreadLocal isDestroying ;
       
   240 
       
   241     // This includes the most important information for debugging
       
   242     // POA problems.
       
   243     public String toString()
       
   244     {
       
   245         return "POA[" + poaId.toString() +
       
   246             ", uniquePOAId=" + uniquePOAId +
       
   247             ", state=" + stateToString() +
       
   248             ", invocationCount=" + invocationCount + "]" ;
       
   249     }
       
   250 
       
   251     // package private for mediator implementations.
       
   252     boolean getDebug()
       
   253     {
       
   254         return debug ;
       
   255     }
       
   256 
       
   257     // package private for access to servant to POA map
       
   258     static POAFactory getPOAFactory( ORB orb )
       
   259     {
       
   260         return (POAFactory)orb.getRequestDispatcherRegistry().
       
   261             getObjectAdapterFactory( ORBConstants.TRANSIENT_SCID ) ;
       
   262     }
       
   263 
       
   264     // package private so that POAFactory can access it.
       
   265     static POAImpl makeRootPOA( ORB orb )
       
   266     {
       
   267         POAManagerImpl poaManager = new POAManagerImpl( getPOAFactory( orb ),
       
   268             orb.getPIHandler() ) ;
       
   269 
       
   270         POAImpl result = new POAImpl( ORBConstants.ROOT_POA_NAME,
       
   271             null, orb, STATE_START ) ;
       
   272         result.initialize( poaManager, Policies.rootPOAPolicies ) ;
       
   273 
       
   274         return result ;
       
   275     }
       
   276 
       
   277     // package private so that POAPolicyMediatorBase can access it.
       
   278     int getPOAId()
       
   279     {
       
   280         return uniquePOAId ;
       
   281     }
       
   282 
       
   283 
       
   284     // package private so that POAPolicyMediator can access it.
       
   285     void lock()
       
   286     {
       
   287         SyncUtil.acquire( poaMutex ) ;
       
   288 
       
   289         if (debug) {
       
   290             ORBUtility.dprint( this, "LOCKED poa " + this ) ;
       
   291         }
       
   292     }
       
   293 
       
   294     // package private so that POAPolicyMediator can access it.
       
   295     void unlock()
       
   296     {
       
   297         if (debug) {
       
   298             ORBUtility.dprint( this, "UNLOCKED poa " + this ) ;
       
   299         }
       
   300 
       
   301         poaMutex.release() ;
       
   302     }
       
   303 
       
   304     // package private so that DelegateImpl can access it.
       
   305     Policies getPolicies()
       
   306     {
       
   307         return mediator.getPolicies() ;
       
   308     }
       
   309 
       
   310     // Note that the parent POA must be locked when this constructor is called.
       
   311     private POAImpl( String name, POAImpl parent, ORB orb, int initialState )
       
   312     {
       
   313         super( orb ) ;
       
   314 
       
   315         debug = orb.poaDebugFlag ;
       
   316 
       
   317         if (debug) {
       
   318             ORBUtility.dprint( this, "Creating POA with name=" + name +
       
   319                 " parent=" + parent ) ;
       
   320         }
       
   321 
       
   322         this.state     = initialState ;
       
   323         this.name      = name ;
       
   324         this.parent    = parent;
       
   325         children = new HashMap();
       
   326         activator = null ;
       
   327 
       
   328         // This was done in initialize, but I moved it here
       
   329         // to get better searchability when tracing.
       
   330         uniquePOAId = getPOAFactory( orb ).newPOAId() ;
       
   331 
       
   332         if (parent == null) {
       
   333             // This is the root POA, which counts as 1 level
       
   334             numLevels = 1 ;
       
   335         } else {
       
   336             // My level is one more than that of my parent
       
   337             numLevels = parent.numLevels + 1 ;
       
   338 
       
   339             parent.children.put(name, this);
       
   340         }
       
   341 
       
   342         // Get an array of all of the POA names in order to
       
   343         // create the poaid.
       
   344         String[] names = new String[ numLevels ] ;
       
   345         POAImpl poaImpl = this ;
       
   346         int ctr = numLevels - 1 ;
       
   347         while (poaImpl != null) {
       
   348             names[ctr--] = poaImpl.name ;
       
   349             poaImpl = poaImpl.parent ;
       
   350         }
       
   351 
       
   352         poaId = new ObjectAdapterIdArray( names ) ;
       
   353 
       
   354         invocationCount = 0;
       
   355 
       
   356         poaMutex = new ReentrantMutex( orb.poaConcurrencyDebugFlag ) ;
       
   357 
       
   358         adapterActivatorCV = new CondVar( poaMutex,
       
   359             orb.poaConcurrencyDebugFlag ) ;
       
   360         invokeCV           = new CondVar( poaMutex,
       
   361             orb.poaConcurrencyDebugFlag ) ;
       
   362         beingDestroyedCV   = new CondVar( poaMutex,
       
   363             orb.poaConcurrencyDebugFlag ) ;
       
   364 
       
   365         isDestroying = new ThreadLocal () {
       
   366             protected java.lang.Object initialValue() {
       
   367                 return Boolean.FALSE;
       
   368             }
       
   369         };
       
   370     }
       
   371 
       
   372     // The POA lock must be held when this method is called.
       
   373     private void initialize( POAManagerImpl manager, Policies policies )
       
   374     {
       
   375         if (debug) {
       
   376             ORBUtility.dprint( this, "Initializing poa " + this +
       
   377                 " with POAManager=" + manager + " policies=" + policies ) ;
       
   378         }
       
   379 
       
   380         this.manager = manager;
       
   381         manager.addPOA(this);
       
   382 
       
   383         mediator = POAPolicyMediatorFactory.create( policies, this ) ;
       
   384 
       
   385         // Construct the object key template
       
   386         int serverid = mediator.getServerId() ;
       
   387         int scid = mediator.getScid() ;
       
   388         String orbId = getORB().getORBData().getORBId();
       
   389 
       
   390         ObjectKeyTemplate oktemp = new POAObjectKeyTemplate( getORB(),
       
   391             scid, serverid, orbId, poaId ) ;
       
   392 
       
   393         if (debug) {
       
   394             ORBUtility.dprint( this, "Initializing poa: oktemp=" + oktemp ) ;
       
   395         }
       
   396 
       
   397         // Note that parent == null iff this is the root POA.
       
   398         // This was used to avoid executing interceptors on the RootPOA.
       
   399         // That is no longer necessary.
       
   400         boolean objectAdapterCreated = true; // parent != null ;
       
   401 
       
   402         // XXX extract codebase from policies and pass into initializeTemplate
       
   403         // after the codebase policy change is finalized.
       
   404         initializeTemplate( oktemp, objectAdapterCreated,
       
   405                             policies,
       
   406                             null, // codebase
       
   407                             null, // manager id
       
   408                             oktemp.getObjectAdapterId()
       
   409                             ) ;
       
   410 
       
   411         if (state == STATE_START)
       
   412             state = STATE_RUN ;
       
   413         else if (state == STATE_INIT)
       
   414             state = STATE_INIT_DONE ;
       
   415         else
       
   416             throw lifecycleWrapper().illegalPoaStateTrans() ;
       
   417     }
       
   418 
       
   419     // The poaMutex must be held when this method is called
       
   420     private boolean waitUntilRunning()
       
   421     {
       
   422         if (debug) {
       
   423             ORBUtility.dprint( this,
       
   424                 "Calling waitUntilRunning on poa " + this ) ;
       
   425         }
       
   426 
       
   427         while (state < STATE_RUN) {
       
   428             try {
       
   429                 adapterActivatorCV.await() ;
       
   430             } catch (InterruptedException exc) {
       
   431                 // NO-OP
       
   432             }
       
   433         }
       
   434 
       
   435         if (debug) {
       
   436             ORBUtility.dprint( this,
       
   437                 "Exiting waitUntilRunning on poa " + this ) ;
       
   438         }
       
   439 
       
   440         // Note that a POA could be destroyed while in STATE_INIT due to a
       
   441         // failure in the AdapterActivator upcall.
       
   442         return (state == STATE_RUN) ;
       
   443     }
       
   444 
       
   445     // This method checks that the AdapterActivator finished the
       
   446     // initialization of a POA activated in find_POA.  This is
       
   447     // determined by checking the state of the POA.  If the state is
       
   448     // STATE_INIT, the AdapterActivator did not complete the
       
   449     // inialization.  In this case, we destroy the POA that was
       
   450     // partially created and return false.  Otherwise, we return true.
       
   451     // In any case, we must wake up all threads waiting for the adapter
       
   452     // activator, either to continue their invocations, or to return
       
   453     // errors to their client.
       
   454     //
       
   455     // The poaMutex must NOT be held when this method is called.
       
   456     private boolean destroyIfNotInitDone()
       
   457     {
       
   458         try {
       
   459             lock() ;
       
   460 
       
   461             if (debug) {
       
   462                 ORBUtility.dprint( this,
       
   463                     "Calling destroyIfNotInitDone on poa " + this ) ;
       
   464             }
       
   465 
       
   466             boolean success = (state == STATE_INIT_DONE) ;
       
   467 
       
   468             if (success)
       
   469                 state = STATE_RUN ;
       
   470             else {
       
   471                 // Don't just use destroy, because the check for
       
   472                 // deadlock is too general, and can prevent this from
       
   473                 // functioning properly.
       
   474                 DestroyThread destroyer = new DestroyThread( false, debug );
       
   475                 destroyer.doIt( this, true ) ;
       
   476             }
       
   477 
       
   478             return success ;
       
   479         } finally {
       
   480             adapterActivatorCV.broadcast() ;
       
   481 
       
   482             if (debug) {
       
   483                 ORBUtility.dprint( this,
       
   484                     "Exiting destroyIfNotInitDone on poa " + this ) ;
       
   485             }
       
   486 
       
   487             unlock() ;
       
   488         }
       
   489     }
       
   490 
       
   491     private byte[] internalReferenceToId(
       
   492         org.omg.CORBA.Object reference ) throws WrongAdapter
       
   493     {
       
   494         IOR ior = ORBUtility.getIOR( reference ) ;
       
   495         IORTemplateList thisTemplate = ior.getIORTemplates() ;
       
   496 
       
   497         ObjectReferenceFactory orf = getCurrentFactory() ;
       
   498         IORTemplateList poaTemplate =
       
   499             IORFactories.getIORTemplateList( orf ) ;
       
   500 
       
   501         if (!poaTemplate.isEquivalent( thisTemplate ))
       
   502             throw new WrongAdapter();
       
   503 
       
   504         // Extract the ObjectId from the first TaggedProfile in the IOR.
       
   505         // If ior was created in this POA, the same ID was used for
       
   506         // every profile through the profile templates in the currentFactory,
       
   507         // so we will get the same result from any profile.
       
   508         Iterator iter = ior.iterator() ;
       
   509         if (!iter.hasNext())
       
   510             throw iorWrapper().noProfilesInIor() ;
       
   511         TaggedProfile prof = (TaggedProfile)(iter.next()) ;
       
   512         ObjectId oid = prof.getObjectId() ;
       
   513 
       
   514         return oid.getId();
       
   515     }
       
   516 
       
   517     // Converted from anonymous class to local class
       
   518     // so that we can call performDestroy() directly.
       
   519     static class DestroyThread extends Thread {
       
   520         private boolean wait ;
       
   521         private boolean etherealize ;
       
   522         private boolean debug ;
       
   523         private POAImpl thePoa ;
       
   524 
       
   525         public DestroyThread( boolean etherealize, boolean debug )
       
   526         {
       
   527             this.etherealize = etherealize ;
       
   528             this.debug = debug ;
       
   529         }
       
   530 
       
   531         public void doIt( POAImpl thePoa, boolean wait )
       
   532         {
       
   533             if (debug) {
       
   534                 ORBUtility.dprint( this,
       
   535                     "Calling DestroyThread.doIt(thePOA=" + thePoa +
       
   536                     " wait=" + wait + " etherealize=" + etherealize ) ;
       
   537             }
       
   538 
       
   539             this.thePoa = thePoa ;
       
   540             this.wait = wait ;
       
   541 
       
   542             if (wait) {
       
   543                 run() ;
       
   544             } else {
       
   545                 // Catch exceptions since setDaemon can cause a
       
   546                 // security exception to be thrown under netscape
       
   547                 // in the Applet mode
       
   548                 try { setDaemon(true); } catch (Exception e) {}
       
   549                 start() ;
       
   550             }
       
   551         }
       
   552 
       
   553         public void run()
       
   554         {
       
   555             Set destroyedPOATemplates = new HashSet() ;
       
   556 
       
   557             performDestroy( thePoa, destroyedPOATemplates );
       
   558 
       
   559             Iterator iter = destroyedPOATemplates.iterator() ;
       
   560             ObjectReferenceTemplate[] orts = new ObjectReferenceTemplate[
       
   561                 destroyedPOATemplates.size() ] ;
       
   562             int index = 0 ;
       
   563             while (iter.hasNext())
       
   564                 orts[ index++ ] = (ObjectReferenceTemplate)iter.next();
       
   565 
       
   566             thePoa.getORB().getPIHandler().adapterStateChanged( orts,
       
   567                 NON_EXISTENT.value ) ;
       
   568         }
       
   569 
       
   570         // Returns true if destruction must be completed, false
       
   571         // if not, which means that another thread is already
       
   572         // destroying poa.
       
   573         private boolean prepareForDestruction( POAImpl poa,
       
   574             Set destroyedPOATemplates )
       
   575         {
       
   576             POAImpl[] childPoas = null ;
       
   577 
       
   578             // Note that we do not synchronize on this, since this is
       
   579             // the PerformDestroy instance, not the POA.
       
   580             try {
       
   581                 poa.lock() ;
       
   582 
       
   583                 if (debug) {
       
   584                     ORBUtility.dprint( this,
       
   585                         "Calling performDestroy on poa " + poa ) ;
       
   586                 }
       
   587 
       
   588                 if (poa.state <= STATE_RUN) {
       
   589                     poa.state = STATE_DESTROYING ;
       
   590                 } else {
       
   591                     // destroy may be called multiple times, and each call
       
   592                     // is allowed to proceed with its own setting of the wait
       
   593                     // flag, but the etherealize value is used from the first
       
   594                     // call to destroy.  Also all children should be destroyed
       
   595                     // before the parent POA.  If the poa is already destroyed,
       
   596                     // we can just return.  If the poa has started destruction,
       
   597                     // but not completed, and wait is true, we need to wait
       
   598                     // until destruction is complete, then just return.
       
   599                     if (wait)
       
   600                         while (poa.state != STATE_DESTROYED) {
       
   601                             try {
       
   602                                 poa.beingDestroyedCV.await() ;
       
   603                             } catch (InterruptedException exc) {
       
   604                                 // NO-OP
       
   605                             }
       
   606                         }
       
   607 
       
   608                     return false ;
       
   609                 }
       
   610 
       
   611                 poa.isDestroying.set(Boolean.TRUE);
       
   612 
       
   613                 // Make a copy since we can't hold the lock while destroying
       
   614                 // the children, and an iterator is not deletion-safe.
       
   615                 childPoas = (POAImpl[])poa.children.values().toArray(
       
   616                     new POAImpl[0] );
       
   617             } finally {
       
   618                 poa.unlock() ;
       
   619             }
       
   620 
       
   621             // We are not holding the POA mutex here to avoid holding it
       
   622             // while destroying the POA's children, since this may involve
       
   623             // upcalls to etherealize methods.
       
   624 
       
   625             for (int ctr=0; ctr<childPoas.length; ctr++ ) {
       
   626                 performDestroy( childPoas[ctr], destroyedPOATemplates ) ;
       
   627             }
       
   628 
       
   629             return true ;
       
   630         }
       
   631 
       
   632         public void performDestroy( POAImpl poa, Set destroyedPOATemplates )
       
   633         {
       
   634             if (!prepareForDestruction( poa, destroyedPOATemplates ))
       
   635                 return ;
       
   636 
       
   637             // NOTE: If we are here, poa is in STATE_DESTROYING state. All
       
   638             // other state checks are taken care of in prepareForDestruction.
       
   639             // No other threads may either be starting new invocations
       
   640             // by calling enter or starting to destroy poa.  There may
       
   641             // still be pending invocations.
       
   642 
       
   643             POAImpl parent = poa.parent ;
       
   644             boolean isRoot = parent == null ;
       
   645 
       
   646             try {
       
   647                 // Note that we must lock the parent before the child.
       
   648                 // The parent lock is required (if poa is not the root)
       
   649                 // to safely remove poa from parent's children Map.
       
   650                 if (!isRoot)
       
   651                     parent.lock() ;
       
   652 
       
   653                 try {
       
   654                     poa.lock() ;
       
   655 
       
   656                     completeDestruction( poa, parent,
       
   657                         destroyedPOATemplates ) ;
       
   658                 } finally {
       
   659                     poa.unlock() ;
       
   660 
       
   661                     if (isRoot)
       
   662                         // We have just destroyed the root POA, so we need to
       
   663                         // make sure that the next call to
       
   664                         // resolve_initial_reference( "RootPOA" )
       
   665                         // will recreate a valid root POA.
       
   666                         poa.manager.getFactory().registerRootPOA() ;
       
   667                 }
       
   668             } finally {
       
   669                 if (!isRoot) {
       
   670                     parent.unlock() ;
       
   671                     poa.parent = null ;
       
   672                 }
       
   673             }
       
   674         }
       
   675 
       
   676         private void completeDestruction( POAImpl poa, POAImpl parent,
       
   677             Set destroyedPOATemplates )
       
   678         {
       
   679             if (debug) {
       
   680                 ORBUtility.dprint( this,
       
   681                     "Calling completeDestruction on poa " + poa ) ;
       
   682             }
       
   683 
       
   684             try {
       
   685                 while (poa.invocationCount != 0) {
       
   686                     try {
       
   687                         poa.invokeCV.await() ;
       
   688                     } catch (InterruptedException ex) {
       
   689                         // NO-OP
       
   690                     }
       
   691                 }
       
   692 
       
   693                 if (poa.mediator != null) {
       
   694                     if (etherealize)
       
   695                         poa.mediator.etherealizeAll();
       
   696 
       
   697                     poa.mediator.clearAOM() ;
       
   698                 }
       
   699 
       
   700                 if (poa.manager != null)
       
   701                     poa.manager.removePOA(poa);
       
   702 
       
   703                 if (parent != null)
       
   704                     parent.children.remove( poa.name ) ;
       
   705 
       
   706                 destroyedPOATemplates.add( poa.getAdapterTemplate() ) ;
       
   707             } catch (Throwable thr) {
       
   708                 if (thr instanceof ThreadDeath)
       
   709                     throw (ThreadDeath)thr ;
       
   710 
       
   711                 poa.lifecycleWrapper().unexpectedException( thr, poa.toString() ) ;
       
   712             } finally {
       
   713                 poa.state = STATE_DESTROYED ;
       
   714                 poa.beingDestroyedCV.broadcast();
       
   715                 poa.isDestroying.set(Boolean.FALSE);
       
   716 
       
   717                 if (debug) {
       
   718                     ORBUtility.dprint( this,
       
   719                         "Exiting completeDestruction on poa " + poa ) ;
       
   720                 }
       
   721             }
       
   722         }
       
   723     }
       
   724 
       
   725     void etherealizeAll()
       
   726     {
       
   727         try {
       
   728             lock() ;
       
   729 
       
   730             if (debug) {
       
   731                 ORBUtility.dprint( this,
       
   732                     "Calling etheralizeAll on poa " + this ) ;
       
   733             }
       
   734 
       
   735             mediator.etherealizeAll() ;
       
   736         } finally {
       
   737             if (debug) {
       
   738                 ORBUtility.dprint( this,
       
   739                     "Exiting etheralizeAll on poa " + this ) ;
       
   740             }
       
   741 
       
   742             unlock() ;
       
   743         }
       
   744     }
       
   745 
       
   746  //*******************************************************************
       
   747  // Public POA API
       
   748  //*******************************************************************
       
   749 
       
   750     /**
       
   751      * <code>create_POA</code>
       
   752      * <b>Section 3.3.8.2</b>
       
   753      */
       
   754     public POA create_POA(String name, POAManager
       
   755         theManager, Policy[] policies) throws AdapterAlreadyExists,
       
   756         InvalidPolicy
       
   757     {
       
   758         try {
       
   759             lock() ;
       
   760 
       
   761             if (debug) {
       
   762                 ORBUtility.dprint( this, "Calling create_POA(name=" + name +
       
   763                     " theManager=" + theManager + " policies=" + policies +
       
   764                     ") on poa " + this ) ;
       
   765             }
       
   766 
       
   767             // We cannot create children of a POA that is (being) destroyed.
       
   768             // This has been added to the CORBA 3.0 spec.
       
   769             if (state > STATE_RUN)
       
   770                 throw omgLifecycleWrapper().createPoaDestroy() ;
       
   771 
       
   772             POAImpl poa = (POAImpl)(children.get(name)) ;
       
   773 
       
   774             if (poa == null) {
       
   775                 poa = new POAImpl( name, this, getORB(), STATE_START ) ;
       
   776             }
       
   777 
       
   778             try {
       
   779                 poa.lock() ;
       
   780 
       
   781                 if (debug) {
       
   782                     ORBUtility.dprint( this,
       
   783                         "Calling create_POA: new poa is " + poa ) ;
       
   784                 }
       
   785 
       
   786                 if ((poa.state != STATE_START) && (poa.state != STATE_INIT))
       
   787                     throw new AdapterAlreadyExists();
       
   788 
       
   789                 POAManagerImpl newManager = (POAManagerImpl)theManager ;
       
   790                 if (newManager == null)
       
   791                     newManager = new POAManagerImpl( manager.getFactory(),
       
   792                         manager.getPIHandler() );
       
   793 
       
   794                 int defaultCopierId =
       
   795                     getORB().getCopierManager().getDefaultId() ;
       
   796                 Policies POAPolicies =
       
   797                     new Policies( policies, defaultCopierId ) ;
       
   798 
       
   799                 poa.initialize( newManager, POAPolicies ) ;
       
   800 
       
   801                 return poa;
       
   802             } finally {
       
   803                 poa.unlock() ;
       
   804             }
       
   805         } finally {
       
   806             unlock() ;
       
   807         }
       
   808     }
       
   809 
       
   810     /**
       
   811      * <code>find_POA</code>
       
   812      * <b>Section 3.3.8.3</b>
       
   813      */
       
   814     public POA find_POA(String name, boolean activate)
       
   815         throws AdapterNonExistent
       
   816     {
       
   817         POAImpl found = null ;
       
   818         AdapterActivator act = null ;
       
   819 
       
   820         lock() ;
       
   821 
       
   822         if (debug) {
       
   823             ORBUtility.dprint( this, "Calling find_POA(name=" + name +
       
   824                 " activate=" + activate + ") on poa " + this ) ;
       
   825         }
       
   826 
       
   827         found = (POAImpl) children.get(name);
       
   828 
       
   829         if (found != null) {
       
   830             if (debug) {
       
   831                 ORBUtility.dprint( this,
       
   832                     "Calling find_POA: found poa " + found ) ;
       
   833             }
       
   834 
       
   835             try {
       
   836                 found.lock() ;
       
   837 
       
   838                 // Do not hold the parent POA lock while
       
   839                 // waiting for child to complete initialization.
       
   840                 unlock() ;
       
   841 
       
   842                 // Make sure that the child has completed its initialization,
       
   843                 // if it was created by an AdapterActivator, otherwise throw
       
   844                 // a standard TRANSIENT exception with minor code 4 (see
       
   845                 // CORBA 3.0 11.3.9.3, in reference to unknown_adapter)
       
   846                 if (!found.waitUntilRunning())
       
   847                     throw omgLifecycleWrapper().poaDestroyed() ;
       
   848 
       
   849                 // Note that found may be in state DESTROYING or DESTROYED at
       
   850                 // this point.  That's OK, since destruction could start at
       
   851                 // any time.
       
   852             } finally {
       
   853                 found.unlock() ;
       
   854             }
       
   855         } else {
       
   856             try {
       
   857                 if (debug) {
       
   858                     ORBUtility.dprint( this,
       
   859                         "Calling find_POA: no poa found" ) ;
       
   860                 }
       
   861 
       
   862                 if (activate && (activator != null)) {
       
   863                     // Create a child, but don't initialize it.  The newly
       
   864                     // created POA will be in state STATE_START, which will
       
   865                     // cause other calls to find_POA that are creating the same
       
   866                     // POA to block on the waitUntilRunning call above.
       
   867                     // Initialization must be completed by a call to create_POA
       
   868                     // inside the unknown_adapter upcall.  Note that
       
   869                     // this.poaMutex must be held here so that this.children
       
   870                     // can be safely updated.  The state is set to STATE_INIT
       
   871                     // so that initialize can make the correct state transition
       
   872                     // when create_POA is called inside the AdapterActivator.
       
   873                     // This avoids activating the new POA too soon
       
   874                     // by transitioning to STATE_RUN after unknown_adapter
       
   875                     // returns.
       
   876                     found = new POAImpl( name, this, getORB(), STATE_INIT ) ;
       
   877 
       
   878                     if (debug) {
       
   879                         ORBUtility.dprint( this,
       
   880                             "Calling find_POA: created poa " + found ) ;
       
   881                     }
       
   882 
       
   883                     act = activator ;
       
   884                 } else {
       
   885                     throw new AdapterNonExistent();
       
   886                 }
       
   887             } finally {
       
   888                 unlock() ;
       
   889             }
       
   890         }
       
   891 
       
   892         // assert (found != null)
       
   893         // assert not holding this.poaMutex OR found.poaMutex
       
   894 
       
   895         // We must not hold either this.poaMutex or found.poaMutex here while
       
   896         // waiting for intialization of found to complete to prevent possible
       
   897         // deadlocks.
       
   898 
       
   899         if (act != null) {
       
   900             boolean status = false ;
       
   901             boolean adapterResult = false ;
       
   902 
       
   903             if (debug) {
       
   904                 ORBUtility.dprint( this,
       
   905                     "Calling find_POA: calling AdapterActivator"  ) ;
       
   906             }
       
   907 
       
   908             try {
       
   909                 // Prevent more than one thread at a time from executing in act
       
   910                 // in case act is shared between multiple POAs.
       
   911                 synchronized (act) {
       
   912                     status = act.unknown_adapter(this, name);
       
   913                 }
       
   914             } catch (SystemException exc) {
       
   915                 throw omgLifecycleWrapper().adapterActivatorException( exc,
       
   916                     name, poaId.toString() ) ;
       
   917             } catch (Throwable thr) {
       
   918                 // ignore most non-system exceptions, but log them for
       
   919                 // diagnostic purposes.
       
   920                 lifecycleWrapper().unexpectedException( thr, this.toString() ) ;
       
   921 
       
   922                 if (thr instanceof ThreadDeath)
       
   923                     throw (ThreadDeath)thr ;
       
   924             } finally {
       
   925                 // At this point, we have completed adapter activation.
       
   926                 // Whether this was successful or not, we must call
       
   927                 // destroyIfNotInitDone so that calls to enter() and create_POA()
       
   928                 // that are waiting can execute again.  Failing to do this
       
   929                 // will cause the system to hang in complex tests.
       
   930                 adapterResult = found.destroyIfNotInitDone() ;
       
   931             }
       
   932 
       
   933             if (status) {
       
   934                 if (!adapterResult)
       
   935                     throw omgLifecycleWrapper().adapterActivatorException( name,
       
   936                         poaId.toString() ) ;
       
   937             } else {
       
   938                 if (debug) {
       
   939                     ORBUtility.dprint( this,
       
   940                         "Calling find_POA: AdapterActivator returned false"  ) ;
       
   941                 }
       
   942 
       
   943                 // OMG Issue 3740 is resolved to throw AdapterNonExistent if
       
   944                 // unknown_adapter() returns false.
       
   945                 throw new AdapterNonExistent();
       
   946             }
       
   947         }
       
   948 
       
   949         return found;
       
   950     }
       
   951 
       
   952     /**
       
   953      * <code>destroy</code>
       
   954      * <b>Section 3.3.8.4</b>
       
   955      */
       
   956     public void destroy(boolean etherealize, boolean wait_for_completion)
       
   957     {
       
   958         // This is to avoid deadlock
       
   959         if (wait_for_completion && getORB().isDuringDispatch()) {
       
   960             throw lifecycleWrapper().destroyDeadlock() ;
       
   961         }
       
   962 
       
   963         DestroyThread destroyer = new DestroyThread( etherealize, debug );
       
   964         destroyer.doIt( this, wait_for_completion ) ;
       
   965     }
       
   966 
       
   967     /**
       
   968      * <code>create_thread_policy</code>
       
   969      * <b>Section 3.3.8.5</b>
       
   970      */
       
   971     public ThreadPolicy create_thread_policy(
       
   972         ThreadPolicyValue value)
       
   973     {
       
   974         return new ThreadPolicyImpl(value);
       
   975     }
       
   976 
       
   977     /**
       
   978      * <code>create_lifespan_policy</code>
       
   979      * <b>Section 3.3.8.5</b>
       
   980      */
       
   981     public LifespanPolicy create_lifespan_policy(
       
   982         LifespanPolicyValue value)
       
   983     {
       
   984         return new LifespanPolicyImpl(value);
       
   985     }
       
   986 
       
   987     /**
       
   988      * <code>create_id_uniqueness_policy</code>
       
   989      * <b>Section 3.3.8.5</b>
       
   990      */
       
   991     public IdUniquenessPolicy create_id_uniqueness_policy(
       
   992         IdUniquenessPolicyValue value)
       
   993     {
       
   994         return new IdUniquenessPolicyImpl(value);
       
   995     }
       
   996 
       
   997     /**
       
   998      * <code>create_id_assignment_policy</code>
       
   999      * <b>Section 3.3.8.5</b>
       
  1000      */
       
  1001     public IdAssignmentPolicy create_id_assignment_policy(
       
  1002         IdAssignmentPolicyValue value)
       
  1003     {
       
  1004         return new IdAssignmentPolicyImpl(value);
       
  1005     }
       
  1006 
       
  1007     /**
       
  1008      * <code>create_implicit_activation_policy</code>
       
  1009      * <b>Section 3.3.8.5</b>
       
  1010      */
       
  1011     public ImplicitActivationPolicy create_implicit_activation_policy(
       
  1012         ImplicitActivationPolicyValue value)
       
  1013     {
       
  1014         return new ImplicitActivationPolicyImpl(value);
       
  1015     }
       
  1016 
       
  1017     /**
       
  1018      * <code>create_servant_retention_policy</code>
       
  1019      * <b>Section 3.3.8.5</b>
       
  1020      */
       
  1021     public ServantRetentionPolicy create_servant_retention_policy(
       
  1022         ServantRetentionPolicyValue value)
       
  1023     {
       
  1024         return new ServantRetentionPolicyImpl(value);
       
  1025     }
       
  1026 
       
  1027     /**
       
  1028      * <code>create_request_processing_policy</code>
       
  1029      * <b>Section 3.3.8.5</b>
       
  1030      */
       
  1031     public RequestProcessingPolicy create_request_processing_policy(
       
  1032         RequestProcessingPolicyValue value)
       
  1033     {
       
  1034         return new RequestProcessingPolicyImpl(value);
       
  1035     }
       
  1036 
       
  1037     /**
       
  1038      * <code>the_name</code>
       
  1039      * <b>Section 3.3.8.6</b>
       
  1040      */
       
  1041     public String the_name()
       
  1042     {
       
  1043         try {
       
  1044             lock() ;
       
  1045 
       
  1046             return name;
       
  1047         } finally {
       
  1048             unlock() ;
       
  1049         }
       
  1050     }
       
  1051 
       
  1052     /**
       
  1053      * <code>the_parent</code>
       
  1054      * <b>Section 3.3.8.7</b>
       
  1055      */
       
  1056     public POA the_parent()
       
  1057     {
       
  1058         try {
       
  1059             lock() ;
       
  1060 
       
  1061             return parent;
       
  1062         } finally {
       
  1063             unlock() ;
       
  1064         }
       
  1065     }
       
  1066 
       
  1067     /**
       
  1068      * <code>the_children</code>
       
  1069      */
       
  1070     public org.omg.PortableServer.POA[] the_children()
       
  1071     {
       
  1072         try {
       
  1073             lock() ;
       
  1074 
       
  1075             Collection coll = children.values() ;
       
  1076             int size = coll.size() ;
       
  1077             POA[] result = new POA[ size ] ;
       
  1078             int index = 0 ;
       
  1079             Iterator iter = coll.iterator() ;
       
  1080             while (iter.hasNext()) {
       
  1081                 POA poa = (POA)(iter.next()) ;
       
  1082                 result[ index++ ] = poa ;
       
  1083             }
       
  1084 
       
  1085             return result ;
       
  1086         } finally {
       
  1087             unlock() ;
       
  1088         }
       
  1089     }
       
  1090 
       
  1091     /**
       
  1092      * <code>the_POAManager</code>
       
  1093      * <b>Section 3.3.8.8</b>
       
  1094      */
       
  1095     public POAManager the_POAManager()
       
  1096     {
       
  1097         try {
       
  1098             lock() ;
       
  1099 
       
  1100             return manager;
       
  1101         } finally {
       
  1102             unlock() ;
       
  1103         }
       
  1104     }
       
  1105 
       
  1106     /**
       
  1107      * <code>the_activator</code>
       
  1108      * <b>Section 3.3.8.9</b>
       
  1109      */
       
  1110     public AdapterActivator the_activator()
       
  1111     {
       
  1112         try {
       
  1113             lock() ;
       
  1114 
       
  1115             return activator;
       
  1116         } finally {
       
  1117             unlock() ;
       
  1118         }
       
  1119     }
       
  1120 
       
  1121     /**
       
  1122      * <code>the_activator</code>
       
  1123      * <b>Section 3.3.8.9</b>
       
  1124      */
       
  1125     public void the_activator(AdapterActivator activator)
       
  1126     {
       
  1127         try {
       
  1128             lock() ;
       
  1129 
       
  1130             if (debug) {
       
  1131                 ORBUtility.dprint( this, "Calling the_activator on poa " +
       
  1132                     this + " activator=" + activator ) ;
       
  1133             }
       
  1134 
       
  1135             this.activator = activator;
       
  1136         } finally {
       
  1137             unlock() ;
       
  1138         }
       
  1139     }
       
  1140 
       
  1141     /**
       
  1142      * <code>get_servant_manager</code>
       
  1143      * <b>Section 3.3.8.10</b>
       
  1144      */
       
  1145     public ServantManager get_servant_manager() throws WrongPolicy
       
  1146     {
       
  1147         try {
       
  1148             lock() ;
       
  1149 
       
  1150             return mediator.getServantManager() ;
       
  1151         } finally {
       
  1152             unlock() ;
       
  1153         }
       
  1154     }
       
  1155 
       
  1156     /**
       
  1157      * <code>set_servant_manager</code>
       
  1158      * <b>Section 3.3.8.10</b>
       
  1159      */
       
  1160     public void set_servant_manager(ServantManager servantManager)
       
  1161         throws WrongPolicy
       
  1162     {
       
  1163         try {
       
  1164             lock() ;
       
  1165 
       
  1166             if (debug) {
       
  1167                 ORBUtility.dprint( this, "Calling set_servant_manager on poa " +
       
  1168                     this + " servantManager=" + servantManager ) ;
       
  1169             }
       
  1170 
       
  1171             mediator.setServantManager( servantManager ) ;
       
  1172         } finally {
       
  1173             unlock() ;
       
  1174         }
       
  1175     }
       
  1176 
       
  1177     /**
       
  1178      * <code>get_servant</code>
       
  1179      * <b>Section 3.3.8.12</b>
       
  1180      */
       
  1181     public Servant get_servant() throws NoServant, WrongPolicy
       
  1182     {
       
  1183         try {
       
  1184             lock() ;
       
  1185 
       
  1186             return mediator.getDefaultServant() ;
       
  1187         } finally {
       
  1188             unlock() ;
       
  1189         }
       
  1190     }
       
  1191 
       
  1192     /**
       
  1193      * <code>set_servant</code>
       
  1194      * <b>Section 3.3.8.13</b>
       
  1195      */
       
  1196     public void set_servant(Servant defaultServant)
       
  1197         throws WrongPolicy
       
  1198     {
       
  1199         try {
       
  1200             lock() ;
       
  1201 
       
  1202             if (debug) {
       
  1203                 ORBUtility.dprint( this, "Calling set_servant on poa " +
       
  1204                     this + " defaultServant=" + defaultServant ) ;
       
  1205             }
       
  1206 
       
  1207             mediator.setDefaultServant( defaultServant ) ;
       
  1208         } finally {
       
  1209             unlock() ;
       
  1210         }
       
  1211     }
       
  1212 
       
  1213     /**
       
  1214      * <code>activate_object</code>
       
  1215      * <b>Section 3.3.8.14</b>
       
  1216      */
       
  1217     public byte[] activate_object(Servant servant)
       
  1218         throws ServantAlreadyActive, WrongPolicy
       
  1219     {
       
  1220         try {
       
  1221             lock() ;
       
  1222 
       
  1223             if (debug) {
       
  1224                 ORBUtility.dprint( this,
       
  1225                     "Calling activate_object on poa " + this +
       
  1226                     " (servant=" + servant + ")" ) ;
       
  1227             }
       
  1228 
       
  1229             // Allocate a new system-generated object-id.
       
  1230             // This will throw WrongPolicy if not SYSTEM_ID
       
  1231             // policy.
       
  1232             byte[] id = mediator.newSystemId();
       
  1233 
       
  1234             try {
       
  1235                 mediator.activateObject( id, servant ) ;
       
  1236             } catch (ObjectAlreadyActive oaa) {
       
  1237                 // This exception can not occur in this case,
       
  1238                 // since id is always brand new.
       
  1239                 //
       
  1240             }
       
  1241 
       
  1242             return id ;
       
  1243         } finally {
       
  1244             if (debug) {
       
  1245                 ORBUtility.dprint( this,
       
  1246                     "Exiting activate_object on poa " + this ) ;
       
  1247             }
       
  1248 
       
  1249             unlock() ;
       
  1250         }
       
  1251     }
       
  1252 
       
  1253     /**
       
  1254      * <code>activate_object_with_id</code>
       
  1255      * <b>Section 3.3.8.15</b>
       
  1256      */
       
  1257     public void activate_object_with_id(byte[] id,
       
  1258                                                      Servant servant)
       
  1259         throws ObjectAlreadyActive, ServantAlreadyActive, WrongPolicy
       
  1260     {
       
  1261         try {
       
  1262             lock() ;
       
  1263 
       
  1264             if (debug) {
       
  1265                 ORBUtility.dprint( this,
       
  1266                     "Calling activate_object_with_id on poa " + this +
       
  1267                     " (servant=" + servant + " id=" + id + ")" ) ;
       
  1268             }
       
  1269 
       
  1270             // Clone the id to avoid possible errors due to aliasing
       
  1271             // (e.g. the client passes the id in and then changes it later).
       
  1272             byte[] idClone = (byte[])(id.clone()) ;
       
  1273 
       
  1274             mediator.activateObject( idClone, servant ) ;
       
  1275         } finally {
       
  1276             if (debug) {
       
  1277                 ORBUtility.dprint( this,
       
  1278                     "Exiting activate_object_with_id on poa " + this ) ;
       
  1279             }
       
  1280 
       
  1281             unlock() ;
       
  1282         }
       
  1283     }
       
  1284 
       
  1285     /**
       
  1286      * <code>deactivate_object</code>
       
  1287      * <b>3.3.8.16</b>
       
  1288      */
       
  1289     public void deactivate_object(byte[] id)
       
  1290         throws ObjectNotActive, WrongPolicy
       
  1291     {
       
  1292         try {
       
  1293             lock() ;
       
  1294 
       
  1295             if (debug) {
       
  1296                 ORBUtility.dprint( this,
       
  1297                     "Calling deactivate_object on poa " + this +
       
  1298                     " (id=" + id + ")" ) ;
       
  1299             }
       
  1300 
       
  1301             mediator.deactivateObject( id ) ;
       
  1302         } finally {
       
  1303             if (debug) {
       
  1304                 ORBUtility.dprint( this,
       
  1305                     "Exiting deactivate_object on poa " + this ) ;
       
  1306             }
       
  1307 
       
  1308             unlock() ;
       
  1309         }
       
  1310     }
       
  1311 
       
  1312     /**
       
  1313      * <code>create_reference</code>
       
  1314      * <b>3.3.8.17</b>
       
  1315      */
       
  1316     public org.omg.CORBA.Object create_reference(String repId)
       
  1317         throws WrongPolicy
       
  1318     {
       
  1319         try {
       
  1320             lock() ;
       
  1321 
       
  1322             if (debug) {
       
  1323                 ORBUtility.dprint( this, "Calling create_reference(repId=" +
       
  1324                     repId + ") on poa " + this ) ;
       
  1325             }
       
  1326 
       
  1327             return makeObject( repId, mediator.newSystemId()) ;
       
  1328         } finally {
       
  1329             unlock() ;
       
  1330         }
       
  1331     }
       
  1332 
       
  1333     /**
       
  1334      * <code>create_reference_with_id</code>
       
  1335      * <b>3.3.8.18</b>
       
  1336      */
       
  1337     public org.omg.CORBA.Object
       
  1338         create_reference_with_id(byte[] oid, String repId)
       
  1339     {
       
  1340         try {
       
  1341             lock() ;
       
  1342 
       
  1343             if (debug) {
       
  1344                 ORBUtility.dprint( this,
       
  1345                     "Calling create_reference_with_id(oid=" +
       
  1346                     oid + " repId=" + repId + ") on poa " + this ) ;
       
  1347             }
       
  1348 
       
  1349             // Clone the id to avoid possible errors due to aliasing
       
  1350             // (e.g. the client passes the id in and then changes it later).
       
  1351             byte[] idClone = (byte[])(oid.clone()) ;
       
  1352 
       
  1353             return makeObject( repId, idClone ) ;
       
  1354         } finally {
       
  1355             unlock() ;
       
  1356         }
       
  1357     }
       
  1358 
       
  1359     /**
       
  1360      * <code>servant_to_id</code>
       
  1361      * <b>3.3.8.19</b>
       
  1362      */
       
  1363     public byte[] servant_to_id(Servant servant)
       
  1364         throws ServantNotActive, WrongPolicy
       
  1365     {
       
  1366         try {
       
  1367             lock() ;
       
  1368 
       
  1369             if (debug) {
       
  1370                 ORBUtility.dprint( this, "Calling servant_to_id(servant=" +
       
  1371                     servant + ") on poa " + this ) ;
       
  1372             }
       
  1373 
       
  1374             return mediator.servantToId( servant ) ;
       
  1375         } finally {
       
  1376             unlock() ;
       
  1377         }
       
  1378     }
       
  1379 
       
  1380     /**
       
  1381      * <code>servant_to_reference</code>
       
  1382      * <b>3.3.8.20</b>
       
  1383      */
       
  1384     public org.omg.CORBA.Object servant_to_reference(Servant servant)
       
  1385         throws ServantNotActive, WrongPolicy
       
  1386     {
       
  1387         try {
       
  1388             lock() ;
       
  1389 
       
  1390             if (debug) {
       
  1391                 ORBUtility.dprint( this,
       
  1392                     "Calling servant_to_reference(servant=" +
       
  1393                     servant + ") on poa " + this ) ;
       
  1394             }
       
  1395 
       
  1396             byte[] oid = mediator.servantToId(servant);
       
  1397             String repId = servant._all_interfaces( this, oid )[0] ;
       
  1398             return create_reference_with_id(oid, repId);
       
  1399         } finally {
       
  1400             unlock() ;
       
  1401         }
       
  1402     }
       
  1403 
       
  1404     /**
       
  1405      * <code>reference_to_servant</code>
       
  1406      * <b>3.3.8.21</b>
       
  1407      */
       
  1408     public Servant reference_to_servant(org.omg.CORBA.Object reference)
       
  1409         throws ObjectNotActive, WrongPolicy, WrongAdapter
       
  1410     {
       
  1411         try {
       
  1412             lock() ;
       
  1413 
       
  1414             if (debug) {
       
  1415                 ORBUtility.dprint( this,
       
  1416                     "Calling reference_to_servant(reference=" +
       
  1417                     reference + ") on poa " + this ) ;
       
  1418             }
       
  1419 
       
  1420             if ( state >= STATE_DESTROYING ) {
       
  1421                 throw lifecycleWrapper().adapterDestroyed() ;
       
  1422             }
       
  1423 
       
  1424             // reference_to_id should throw WrongAdapter
       
  1425             // if the objref was not created by this POA
       
  1426             byte [] id = internalReferenceToId(reference);
       
  1427 
       
  1428             return mediator.idToServant( id ) ;
       
  1429         } finally {
       
  1430             unlock() ;
       
  1431         }
       
  1432     }
       
  1433 
       
  1434     /**
       
  1435      * <code>reference_to_id</code>
       
  1436      * <b>3.3.8.22</b>
       
  1437      */
       
  1438     public byte[] reference_to_id(org.omg.CORBA.Object reference)
       
  1439         throws WrongAdapter, WrongPolicy
       
  1440     {
       
  1441         try {
       
  1442             lock() ;
       
  1443 
       
  1444             if (debug) {
       
  1445                 ORBUtility.dprint( this, "Calling reference_to_id(reference=" +
       
  1446                     reference + ") on poa " + this ) ;
       
  1447             }
       
  1448 
       
  1449             if( state >= STATE_DESTROYING ) {
       
  1450                 throw lifecycleWrapper().adapterDestroyed() ;
       
  1451             }
       
  1452 
       
  1453             return internalReferenceToId( reference ) ;
       
  1454         } finally {
       
  1455             unlock() ;
       
  1456         }
       
  1457     }
       
  1458 
       
  1459     /**
       
  1460      * <code>id_to_servant</code>
       
  1461      * <b>3.3.8.23</b>
       
  1462      */
       
  1463     public Servant id_to_servant(byte[] id)
       
  1464         throws ObjectNotActive, WrongPolicy
       
  1465     {
       
  1466         try {
       
  1467             lock() ;
       
  1468 
       
  1469             if (debug) {
       
  1470                 ORBUtility.dprint( this, "Calling id_to_servant(id=" +
       
  1471                     id + ") on poa " + this ) ;
       
  1472             }
       
  1473 
       
  1474             if( state >= STATE_DESTROYING ) {
       
  1475                 throw lifecycleWrapper().adapterDestroyed() ;
       
  1476             }
       
  1477             return mediator.idToServant( id ) ;
       
  1478         } finally {
       
  1479             unlock() ;
       
  1480         }
       
  1481     }
       
  1482 
       
  1483     /**
       
  1484      * <code>id_to_reference</code>
       
  1485      * <b>3.3.8.24</b>
       
  1486      */
       
  1487     public org.omg.CORBA.Object id_to_reference(byte[] id)
       
  1488         throws ObjectNotActive, WrongPolicy
       
  1489 
       
  1490     {
       
  1491         try {
       
  1492             lock() ;
       
  1493 
       
  1494             if (debug) {
       
  1495                 ORBUtility.dprint( this, "Calling id_to_reference(id=" +
       
  1496                     id + ") on poa " + this ) ;
       
  1497             }
       
  1498 
       
  1499             if( state >= STATE_DESTROYING ) {
       
  1500                 throw lifecycleWrapper().adapterDestroyed() ;
       
  1501             }
       
  1502 
       
  1503             Servant s = mediator.idToServant( id ) ;
       
  1504             String repId = s._all_interfaces( this, id )[0] ;
       
  1505             return makeObject(repId, id );
       
  1506         } finally {
       
  1507             unlock() ;
       
  1508         }
       
  1509     }
       
  1510 
       
  1511     /**
       
  1512      * <code>id</code>
       
  1513      * <b>11.3.8.26 in ptc/00-08-06</b>
       
  1514      */
       
  1515     public byte[] id()
       
  1516     {
       
  1517         try {
       
  1518             lock() ;
       
  1519 
       
  1520             return getAdapterId() ;
       
  1521         } finally {
       
  1522             unlock() ;
       
  1523         }
       
  1524     }
       
  1525 
       
  1526     //***************************************************************
       
  1527     //Implementation of ObjectAdapter interface
       
  1528     //***************************************************************
       
  1529 
       
  1530     public Policy getEffectivePolicy( int type )
       
  1531     {
       
  1532         return mediator.getPolicies().get_effective_policy( type ) ;
       
  1533     }
       
  1534 
       
  1535     public int getManagerId()
       
  1536     {
       
  1537         return manager.getManagerId() ;
       
  1538     }
       
  1539 
       
  1540     public short getState()
       
  1541     {
       
  1542         return manager.getORTState() ;
       
  1543     }
       
  1544 
       
  1545     public String[] getInterfaces( java.lang.Object servant, byte[] objectId )
       
  1546     {
       
  1547         Servant serv = (Servant)servant ;
       
  1548         return serv._all_interfaces( this, objectId ) ;
       
  1549     }
       
  1550 
       
  1551     protected ObjectCopierFactory getObjectCopierFactory()
       
  1552     {
       
  1553         int copierId = mediator.getPolicies().getCopierId() ;
       
  1554         CopierManager cm = getORB().getCopierManager() ;
       
  1555         return cm.getObjectCopierFactory( copierId ) ;
       
  1556     }
       
  1557 
       
  1558     public void enter() throws OADestroyed
       
  1559     {
       
  1560         try {
       
  1561             lock() ;
       
  1562 
       
  1563             if (debug) {
       
  1564                 ORBUtility.dprint( this, "Calling enter on poa " + this ) ;
       
  1565             }
       
  1566 
       
  1567             // Avoid deadlock if this is the thread that is processing the
       
  1568             // POA.destroy because this is the only thread that can notify
       
  1569             // waiters on beingDestroyedCV.  This can happen if an
       
  1570             // etherealize upcall invokes a method on a colocated object
       
  1571             // served by this POA.
       
  1572             while ((state == STATE_DESTROYING) &&
       
  1573                 (isDestroying.get() == Boolean.FALSE)) {
       
  1574                 try {
       
  1575                     beingDestroyedCV.await();
       
  1576                 } catch (InterruptedException ex) {
       
  1577                     // NO-OP
       
  1578                 }
       
  1579             }
       
  1580 
       
  1581             if (!waitUntilRunning())
       
  1582                 throw new OADestroyed() ;
       
  1583 
       
  1584             invocationCount++;
       
  1585         } finally {
       
  1586             if (debug) {
       
  1587                 ORBUtility.dprint( this, "Exiting enter on poa " + this ) ;
       
  1588             }
       
  1589 
       
  1590             unlock() ;
       
  1591         }
       
  1592 
       
  1593         manager.enter();
       
  1594     }
       
  1595 
       
  1596     public void exit()
       
  1597     {
       
  1598         try {
       
  1599             lock() ;
       
  1600 
       
  1601             if (debug) {
       
  1602                 ORBUtility.dprint( this, "Calling exit on poa " + this ) ;
       
  1603             }
       
  1604 
       
  1605             invocationCount--;
       
  1606 
       
  1607             if ((invocationCount == 0) && (state == STATE_DESTROYING)) {
       
  1608                 invokeCV.broadcast();
       
  1609             }
       
  1610         } finally {
       
  1611             if (debug) {
       
  1612                 ORBUtility.dprint( this, "Exiting exit on poa " + this ) ;
       
  1613             }
       
  1614 
       
  1615             unlock() ;
       
  1616         }
       
  1617 
       
  1618         manager.exit();
       
  1619     }
       
  1620 
       
  1621     public void getInvocationServant( OAInvocationInfo info )
       
  1622     {
       
  1623         try {
       
  1624             lock() ;
       
  1625 
       
  1626             if (debug) {
       
  1627                 ORBUtility.dprint( this,
       
  1628                     "Calling getInvocationServant on poa " + this ) ;
       
  1629             }
       
  1630 
       
  1631             java.lang.Object servant = null ;
       
  1632 
       
  1633             try {
       
  1634                 servant = mediator.getInvocationServant( info.id(),
       
  1635                     info.getOperation() );
       
  1636             } catch (ForwardRequest freq) {
       
  1637                 throw new ForwardException( getORB(), freq.forward_reference ) ;
       
  1638             }
       
  1639 
       
  1640             info.setServant( servant ) ;
       
  1641         } finally {
       
  1642             if (debug) {
       
  1643                 ORBUtility.dprint( this,
       
  1644                     "Exiting getInvocationServant on poa " + this ) ;
       
  1645             }
       
  1646 
       
  1647             unlock() ;
       
  1648         }
       
  1649     }
       
  1650 
       
  1651     public org.omg.CORBA.Object getLocalServant( byte[] objectId )
       
  1652     {
       
  1653         return null ;
       
  1654     }
       
  1655 
       
  1656     /** Called from the subcontract to let this POA cleanup after an
       
  1657      *  invocation. Note: If getServant was called, then returnServant
       
  1658      *  MUST be called, even in the case of exceptions.  This may be
       
  1659      *  called multiple times for a single request.
       
  1660      */
       
  1661     public void returnServant()
       
  1662     {
       
  1663         try {
       
  1664             lock() ;
       
  1665 
       
  1666             if (debug) {
       
  1667                 ORBUtility.dprint( this,
       
  1668                     "Calling returnServant on poa " + this  ) ;
       
  1669             }
       
  1670 
       
  1671             mediator.returnServant();
       
  1672         } catch (Throwable thr) {
       
  1673             if (debug) {
       
  1674                 ORBUtility.dprint( this,
       
  1675                     "Exception " + thr + " in returnServant on poa " + this  ) ;
       
  1676             }
       
  1677 
       
  1678             if (thr instanceof Error)
       
  1679                 throw (Error)thr ;
       
  1680             else if (thr instanceof RuntimeException)
       
  1681                 throw (RuntimeException)thr ;
       
  1682 
       
  1683         } finally {
       
  1684             if (debug) {
       
  1685                 ORBUtility.dprint( this,
       
  1686                     "Exiting returnServant on poa " + this  ) ;
       
  1687             }
       
  1688 
       
  1689             unlock() ;
       
  1690         }
       
  1691     }
       
  1692 }