1 /* 2 * Copyright (c) 1997, 2015, 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 sun.misc.ManagedLocalsThread { 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 }