*/
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) {