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 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 super(null, null, "POA-Destroy-Thread", 0, false); 528 this.etherealize = etherealize ; 529 this.debug = debug ; 530 } 531 532 public void doIt( POAImpl thePoa, boolean wait ) 533 { 534 if (debug) { 535 ORBUtility.dprint( this, 536 "Calling DestroyThread.doIt(thePOA=" + thePoa + 537 " wait=" + wait + " etherealize=" + etherealize ) ; 538 } 539 540 this.thePoa = thePoa ; 541 this.wait = wait ; 542 543 if (wait) { 544 run() ; 545 } else { 546 // Catch exceptions since setDaemon can cause a 547 // security exception to be thrown under netscape 548 // in the Applet mode 549 try { setDaemon(true); } catch (Exception e) {} 550 start() ; 551 } 552 } 553 554 public void run() 555 { 556 Set destroyedPOATemplates = new HashSet() ; 557 558 performDestroy( thePoa, destroyedPOATemplates ); 559 560 Iterator iter = destroyedPOATemplates.iterator() ; 561 ObjectReferenceTemplate[] orts = new ObjectReferenceTemplate[ 562 destroyedPOATemplates.size() ] ; 563 int index = 0 ; 564 while (iter.hasNext()) 565 orts[ index++ ] = (ObjectReferenceTemplate)iter.next(); 566 567 thePoa.getORB().getPIHandler().adapterStateChanged( orts, 568 NON_EXISTENT.value ) ; 569 } 570 571 // Returns true if destruction must be completed, false 572 // if not, which means that another thread is already 573 // destroying poa. 574 private boolean prepareForDestruction( POAImpl poa, 575 Set destroyedPOATemplates ) 576 { 577 POAImpl[] childPoas = null ; 578 579 // Note that we do not synchronize on this, since this is 580 // the PerformDestroy instance, not the POA. 581 try { 582 poa.lock() ; 583 584 if (debug) { 585 ORBUtility.dprint( this, 586 "Calling performDestroy on poa " + poa ) ; 587 } 588 589 if (poa.state <= STATE_RUN) { 590 poa.state = STATE_DESTROYING ; 591 } else { 592 // destroy may be called multiple times, and each call 593 // is allowed to proceed with its own setting of the wait 594 // flag, but the etherealize value is used from the first 595 // call to destroy. Also all children should be destroyed 596 // before the parent POA. If the poa is already destroyed, 597 // we can just return. If the poa has started destruction, 598 // but not completed, and wait is true, we need to wait 599 // until destruction is complete, then just return. 600 if (wait) 601 while (poa.state != STATE_DESTROYED) { 602 try { 603 poa.beingDestroyedCV.await() ; 604 } catch (InterruptedException exc) { 605 // NO-OP 606 } 607 } 608 609 return false ; 610 } 611 612 poa.isDestroying.set(Boolean.TRUE); 613 614 // Make a copy since we can't hold the lock while destroying 615 // the children, and an iterator is not deletion-safe. 616 childPoas = (POAImpl[])poa.children.values().toArray( 617 new POAImpl[0] ); 618 } finally { 619 poa.unlock() ; 620 } 621 622 // We are not holding the POA mutex here to avoid holding it 623 // while destroying the POA's children, since this may involve 624 // upcalls to etherealize methods. 625 626 for (int ctr=0; ctr<childPoas.length; ctr++ ) { 627 performDestroy( childPoas[ctr], destroyedPOATemplates ) ; 628 } 629 630 return true ; 631 } 632 633 public void performDestroy( POAImpl poa, Set destroyedPOATemplates ) 634 { 635 if (!prepareForDestruction( poa, destroyedPOATemplates )) 636 return ; 637 638 // NOTE: If we are here, poa is in STATE_DESTROYING state. All 639 // other state checks are taken care of in prepareForDestruction. 640 // No other threads may either be starting new invocations 641 // by calling enter or starting to destroy poa. There may 642 // still be pending invocations. 643 644 POAImpl parent = poa.parent ; 645 boolean isRoot = parent == null ; 646 647 try { 648 // Note that we must lock the parent before the child. 649 // The parent lock is required (if poa is not the root) 650 // to safely remove poa from parent's children Map. 651 if (!isRoot) 652 parent.lock() ; 653 654 try { 655 poa.lock() ; 656 657 completeDestruction( poa, parent, 658 destroyedPOATemplates ) ; 659 } finally { 660 poa.unlock() ; 661 662 if (isRoot) 663 // We have just destroyed the root POA, so we need to 664 // make sure that the next call to 665 // resolve_initial_reference( "RootPOA" ) 666 // will recreate a valid root POA. 667 poa.manager.getFactory().registerRootPOA() ; 668 } 669 } finally { 670 if (!isRoot) { 671 parent.unlock() ; 672 poa.parent = null ; 673 } 674 } 675 } 676 677 private void completeDestruction( POAImpl poa, POAImpl parent, 678 Set destroyedPOATemplates ) 679 { 680 if (debug) { 681 ORBUtility.dprint( this, 682 "Calling completeDestruction on poa " + poa ) ; 683 } 684 685 try { 686 while (poa.invocationCount != 0) { 687 try { 688 poa.invokeCV.await() ; 689 } catch (InterruptedException ex) { 690 // NO-OP 691 } 692 } 693 694 if (poa.mediator != null) { 695 if (etherealize) 696 poa.mediator.etherealizeAll(); 697 698 poa.mediator.clearAOM() ; 699 } 700 701 if (poa.manager != null) 702 poa.manager.removePOA(poa); 703 704 if (parent != null) 705 parent.children.remove( poa.name ) ; 706 707 destroyedPOATemplates.add( poa.getAdapterTemplate() ) ; 708 } catch (Throwable thr) { 709 if (thr instanceof ThreadDeath) 710 throw (ThreadDeath)thr ; 711 712 poa.lifecycleWrapper().unexpectedException( thr, poa.toString() ) ; 713 } finally { 714 poa.state = STATE_DESTROYED ; 715 poa.beingDestroyedCV.broadcast(); 716 poa.isDestroying.set(Boolean.FALSE); 717 718 if (debug) { 719 ORBUtility.dprint( this, 720 "Exiting completeDestruction on poa " + poa ) ; 721 } 722 } 723 } 724 } 725 726 void etherealizeAll() 727 { 728 try { 729 lock() ; 730 731 if (debug) { 732 ORBUtility.dprint( this, 733 "Calling etheralizeAll on poa " + this ) ; 734 } 735 736 mediator.etherealizeAll() ; 737 } finally { 738 if (debug) { 739 ORBUtility.dprint( this, 740 "Exiting etheralizeAll on poa " + this ) ; 741 } 742 743 unlock() ; 744 } 745 } 746 747 //******************************************************************* 748 // Public POA API 749 //******************************************************************* 750 751 /** 752 * <code>create_POA</code> 753 * <b>Section 3.3.8.2</b> 754 */ 755 public POA create_POA(String name, POAManager 756 theManager, Policy[] policies) throws AdapterAlreadyExists, 757 InvalidPolicy 758 { 759 try { 760 lock() ; 761 762 if (debug) { 763 ORBUtility.dprint( this, "Calling create_POA(name=" + name + 764 " theManager=" + theManager + " policies=" + policies + 765 ") on poa " + this ) ; 766 } 767 768 // We cannot create children of a POA that is (being) destroyed. 769 // This has been added to the CORBA 3.0 spec. 770 if (state > STATE_RUN) 771 throw omgLifecycleWrapper().createPoaDestroy() ; 772 773 POAImpl poa = (POAImpl)(children.get(name)) ; 774 775 if (poa == null) { 776 poa = new POAImpl( name, this, getORB(), STATE_START ) ; 777 } 778 779 try { 780 poa.lock() ; 781 782 if (debug) { 783 ORBUtility.dprint( this, 784 "Calling create_POA: new poa is " + poa ) ; 785 } 786 787 if ((poa.state != STATE_START) && (poa.state != STATE_INIT)) 788 throw new AdapterAlreadyExists(); 789 790 POAManagerImpl newManager = (POAManagerImpl)theManager ; 791 if (newManager == null) 792 newManager = new POAManagerImpl( manager.getFactory(), 793 manager.getPIHandler() ); 794 795 int defaultCopierId = 796 getORB().getCopierManager().getDefaultId() ; 797 Policies POAPolicies = 798 new Policies( policies, defaultCopierId ) ; 799 800 poa.initialize( newManager, POAPolicies ) ; 801 802 return poa; 803 } finally { 804 poa.unlock() ; 805 } 806 } finally { 807 unlock() ; 808 } 809 } 810 811 /** 812 * <code>find_POA</code> 813 * <b>Section 3.3.8.3</b> 814 */ 815 public POA find_POA(String name, boolean activate) 816 throws AdapterNonExistent 817 { 818 POAImpl found = null ; 819 AdapterActivator act = null ; 820 821 lock() ; 822 823 if (debug) { 824 ORBUtility.dprint( this, "Calling find_POA(name=" + name + 825 " activate=" + activate + ") on poa " + this ) ; 826 } 827 828 found = (POAImpl) children.get(name); 829 830 if (found != null) { 831 if (debug) { 832 ORBUtility.dprint( this, 833 "Calling find_POA: found poa " + found ) ; 834 } 835 836 try { 837 found.lock() ; 838 839 // Do not hold the parent POA lock while 840 // waiting for child to complete initialization. 841 unlock() ; 842 843 // Make sure that the child has completed its initialization, 844 // if it was created by an AdapterActivator, otherwise throw 845 // a standard TRANSIENT exception with minor code 4 (see 846 // CORBA 3.0 11.3.9.3, in reference to unknown_adapter) 847 if (!found.waitUntilRunning()) 848 throw omgLifecycleWrapper().poaDestroyed() ; 849 850 // Note that found may be in state DESTROYING or DESTROYED at 851 // this point. That's OK, since destruction could start at 852 // any time. 853 } finally { 854 found.unlock() ; 855 } 856 } else { 857 try { 858 if (debug) { 859 ORBUtility.dprint( this, 860 "Calling find_POA: no poa found" ) ; 861 } 862 863 if (activate && (activator != null)) { 864 // Create a child, but don't initialize it. The newly 865 // created POA will be in state STATE_START, which will 866 // cause other calls to find_POA that are creating the same 867 // POA to block on the waitUntilRunning call above. 868 // Initialization must be completed by a call to create_POA 869 // inside the unknown_adapter upcall. Note that 870 // this.poaMutex must be held here so that this.children 871 // can be safely updated. The state is set to STATE_INIT 872 // so that initialize can make the correct state transition 873 // when create_POA is called inside the AdapterActivator. 874 // This avoids activating the new POA too soon 875 // by transitioning to STATE_RUN after unknown_adapter 876 // returns. 877 found = new POAImpl( name, this, getORB(), STATE_INIT ) ; 878 879 if (debug) { 880 ORBUtility.dprint( this, 881 "Calling find_POA: created poa " + found ) ; 882 } 883 884 act = activator ; 885 } else { 886 throw new AdapterNonExistent(); 887 } 888 } finally { 889 unlock() ; 890 } 891 } 892 893 // assert (found != null) 894 // assert not holding this.poaMutex OR found.poaMutex 895 896 // We must not hold either this.poaMutex or found.poaMutex here while 897 // waiting for intialization of found to complete to prevent possible 898 // deadlocks. 899 900 if (act != null) { 901 boolean status = false ; 902 boolean adapterResult = false ; 903 904 if (debug) { 905 ORBUtility.dprint( this, 906 "Calling find_POA: calling AdapterActivator" ) ; 907 } 908 909 try { 910 // Prevent more than one thread at a time from executing in act 911 // in case act is shared between multiple POAs. 912 synchronized (act) { 913 status = act.unknown_adapter(this, name); 914 } 915 } catch (SystemException exc) { 916 throw omgLifecycleWrapper().adapterActivatorException( exc, 917 name, poaId.toString() ) ; 918 } catch (Throwable thr) { 919 // ignore most non-system exceptions, but log them for 920 // diagnostic purposes. 921 lifecycleWrapper().unexpectedException( thr, this.toString() ) ; 922 923 if (thr instanceof ThreadDeath) 924 throw (ThreadDeath)thr ; 925 } finally { 926 // At this point, we have completed adapter activation. 927 // Whether this was successful or not, we must call 928 // destroyIfNotInitDone so that calls to enter() and create_POA() 929 // that are waiting can execute again. Failing to do this 930 // will cause the system to hang in complex tests. 931 adapterResult = found.destroyIfNotInitDone() ; 932 } 933 934 if (status) { 935 if (!adapterResult) 936 throw omgLifecycleWrapper().adapterActivatorException( name, 937 poaId.toString() ) ; 938 } else { 939 if (debug) { 940 ORBUtility.dprint( this, 941 "Calling find_POA: AdapterActivator returned false" ) ; 942 } 943 944 // OMG Issue 3740 is resolved to throw AdapterNonExistent if 945 // unknown_adapter() returns false. 946 throw new AdapterNonExistent(); 947 } 948 } 949 950 return found; 951 } 952 953 /** 954 * <code>destroy</code> 955 * <b>Section 3.3.8.4</b> 956 */ 957 public void destroy(boolean etherealize, boolean wait_for_completion) 958 { 959 // This is to avoid deadlock 960 if (wait_for_completion && getORB().isDuringDispatch()) { 961 throw lifecycleWrapper().destroyDeadlock() ; 962 } 963 964 DestroyThread destroyer = new DestroyThread( etherealize, debug ); 965 destroyer.doIt( this, wait_for_completion ) ; 966 } 967 968 /** 969 * <code>create_thread_policy</code> 970 * <b>Section 3.3.8.5</b> 971 */ 972 public ThreadPolicy create_thread_policy( 973 ThreadPolicyValue value) 974 { 975 return new ThreadPolicyImpl(value); 976 } 977 978 /** 979 * <code>create_lifespan_policy</code> 980 * <b>Section 3.3.8.5</b> 981 */ 982 public LifespanPolicy create_lifespan_policy( 983 LifespanPolicyValue value) 984 { 985 return new LifespanPolicyImpl(value); 986 } 987 988 /** 989 * <code>create_id_uniqueness_policy</code> 990 * <b>Section 3.3.8.5</b> 991 */ 992 public IdUniquenessPolicy create_id_uniqueness_policy( 993 IdUniquenessPolicyValue value) 994 { 995 return new IdUniquenessPolicyImpl(value); 996 } 997 998 /** 999 * <code>create_id_assignment_policy</code> 1000 * <b>Section 3.3.8.5</b> 1001 */ 1002 public IdAssignmentPolicy create_id_assignment_policy( 1003 IdAssignmentPolicyValue value) 1004 { 1005 return new IdAssignmentPolicyImpl(value); 1006 } 1007 1008 /** 1009 * <code>create_implicit_activation_policy</code> 1010 * <b>Section 3.3.8.5</b> 1011 */ 1012 public ImplicitActivationPolicy create_implicit_activation_policy( 1013 ImplicitActivationPolicyValue value) 1014 { 1015 return new ImplicitActivationPolicyImpl(value); 1016 } 1017 1018 /** 1019 * <code>create_servant_retention_policy</code> 1020 * <b>Section 3.3.8.5</b> 1021 */ 1022 public ServantRetentionPolicy create_servant_retention_policy( 1023 ServantRetentionPolicyValue value) 1024 { 1025 return new ServantRetentionPolicyImpl(value); 1026 } 1027 1028 /** 1029 * <code>create_request_processing_policy</code> 1030 * <b>Section 3.3.8.5</b> 1031 */ 1032 public RequestProcessingPolicy create_request_processing_policy( 1033 RequestProcessingPolicyValue value) 1034 { 1035 return new RequestProcessingPolicyImpl(value); 1036 } 1037 1038 /** 1039 * <code>the_name</code> 1040 * <b>Section 3.3.8.6</b> 1041 */ 1042 public String the_name() 1043 { 1044 try { 1045 lock() ; 1046 1047 return name; 1048 } finally { 1049 unlock() ; 1050 } 1051 } 1052 1053 /** 1054 * <code>the_parent</code> 1055 * <b>Section 3.3.8.7</b> 1056 */ 1057 public POA the_parent() 1058 { 1059 try { 1060 lock() ; 1061 1062 return parent; 1063 } finally { 1064 unlock() ; 1065 } 1066 } 1067 1068 /** 1069 * <code>the_children</code> 1070 */ 1071 public org.omg.PortableServer.POA[] the_children() 1072 { 1073 try { 1074 lock() ; 1075 1076 Collection coll = children.values() ; 1077 int size = coll.size() ; 1078 POA[] result = new POA[ size ] ; 1079 int index = 0 ; 1080 Iterator iter = coll.iterator() ; 1081 while (iter.hasNext()) { 1082 POA poa = (POA)(iter.next()) ; 1083 result[ index++ ] = poa ; 1084 } 1085 1086 return result ; 1087 } finally { 1088 unlock() ; 1089 } 1090 } 1091 1092 /** 1093 * <code>the_POAManager</code> 1094 * <b>Section 3.3.8.8</b> 1095 */ 1096 public POAManager the_POAManager() 1097 { 1098 try { 1099 lock() ; 1100 1101 return manager; 1102 } finally { 1103 unlock() ; 1104 } 1105 } 1106 1107 /** 1108 * <code>the_activator</code> 1109 * <b>Section 3.3.8.9</b> 1110 */ 1111 public AdapterActivator the_activator() 1112 { 1113 try { 1114 lock() ; 1115 1116 return activator; 1117 } finally { 1118 unlock() ; 1119 } 1120 } 1121 1122 /** 1123 * <code>the_activator</code> 1124 * <b>Section 3.3.8.9</b> 1125 */ 1126 public void the_activator(AdapterActivator activator) 1127 { 1128 try { 1129 lock() ; 1130 1131 if (debug) { 1132 ORBUtility.dprint( this, "Calling the_activator on poa " + 1133 this + " activator=" + activator ) ; 1134 } 1135 1136 this.activator = activator; 1137 } finally { 1138 unlock() ; 1139 } 1140 } 1141 1142 /** 1143 * <code>get_servant_manager</code> 1144 * <b>Section 3.3.8.10</b> 1145 */ 1146 public ServantManager get_servant_manager() throws WrongPolicy 1147 { 1148 try { 1149 lock() ; 1150 1151 return mediator.getServantManager() ; 1152 } finally { 1153 unlock() ; 1154 } 1155 } 1156 1157 /** 1158 * <code>set_servant_manager</code> 1159 * <b>Section 3.3.8.10</b> 1160 */ 1161 public void set_servant_manager(ServantManager servantManager) 1162 throws WrongPolicy 1163 { 1164 try { 1165 lock() ; 1166 1167 if (debug) { 1168 ORBUtility.dprint( this, "Calling set_servant_manager on poa " + 1169 this + " servantManager=" + servantManager ) ; 1170 } 1171 1172 mediator.setServantManager( servantManager ) ; 1173 } finally { 1174 unlock() ; 1175 } 1176 } 1177 1178 /** 1179 * <code>get_servant</code> 1180 * <b>Section 3.3.8.12</b> 1181 */ 1182 public Servant get_servant() throws NoServant, WrongPolicy 1183 { 1184 try { 1185 lock() ; 1186 1187 return mediator.getDefaultServant() ; 1188 } finally { 1189 unlock() ; 1190 } 1191 } 1192 1193 /** 1194 * <code>set_servant</code> 1195 * <b>Section 3.3.8.13</b> 1196 */ 1197 public void set_servant(Servant defaultServant) 1198 throws WrongPolicy 1199 { 1200 try { 1201 lock() ; 1202 1203 if (debug) { 1204 ORBUtility.dprint( this, "Calling set_servant on poa " + 1205 this + " defaultServant=" + defaultServant ) ; 1206 } 1207 1208 mediator.setDefaultServant( defaultServant ) ; 1209 } finally { 1210 unlock() ; 1211 } 1212 } 1213 1214 /** 1215 * <code>activate_object</code> 1216 * <b>Section 3.3.8.14</b> 1217 */ 1218 public byte[] activate_object(Servant servant) 1219 throws ServantAlreadyActive, WrongPolicy 1220 { 1221 try { 1222 lock() ; 1223 1224 if (debug) { 1225 ORBUtility.dprint( this, 1226 "Calling activate_object on poa " + this + 1227 " (servant=" + servant + ")" ) ; 1228 } 1229 1230 // Allocate a new system-generated object-id. 1231 // This will throw WrongPolicy if not SYSTEM_ID 1232 // policy. 1233 byte[] id = mediator.newSystemId(); 1234 1235 try { 1236 mediator.activateObject( id, servant ) ; 1237 } catch (ObjectAlreadyActive oaa) { 1238 // This exception can not occur in this case, 1239 // since id is always brand new. 1240 // 1241 } 1242 1243 return id ; 1244 } finally { 1245 if (debug) { 1246 ORBUtility.dprint( this, 1247 "Exiting activate_object on poa " + this ) ; 1248 } 1249 1250 unlock() ; 1251 } 1252 } 1253 1254 /** 1255 * <code>activate_object_with_id</code> 1256 * <b>Section 3.3.8.15</b> 1257 */ 1258 public void activate_object_with_id(byte[] id, 1259 Servant servant) 1260 throws ObjectAlreadyActive, ServantAlreadyActive, WrongPolicy 1261 { 1262 try { 1263 lock() ; 1264 1265 if (debug) { 1266 ORBUtility.dprint( this, 1267 "Calling activate_object_with_id on poa " + this + 1268 " (servant=" + servant + " id=" + id + ")" ) ; 1269 } 1270 1271 // Clone the id to avoid possible errors due to aliasing 1272 // (e.g. the client passes the id in and then changes it later). 1273 byte[] idClone = (byte[])(id.clone()) ; 1274 1275 mediator.activateObject( idClone, servant ) ; 1276 } finally { 1277 if (debug) { 1278 ORBUtility.dprint( this, 1279 "Exiting activate_object_with_id on poa " + this ) ; 1280 } 1281 1282 unlock() ; 1283 } 1284 } 1285 1286 /** 1287 * <code>deactivate_object</code> 1288 * <b>3.3.8.16</b> 1289 */ 1290 public void deactivate_object(byte[] id) 1291 throws ObjectNotActive, WrongPolicy 1292 { 1293 try { 1294 lock() ; 1295 1296 if (debug) { 1297 ORBUtility.dprint( this, 1298 "Calling deactivate_object on poa " + this + 1299 " (id=" + id + ")" ) ; 1300 } 1301 1302 mediator.deactivateObject( id ) ; 1303 } finally { 1304 if (debug) { 1305 ORBUtility.dprint( this, 1306 "Exiting deactivate_object on poa " + this ) ; 1307 } 1308 1309 unlock() ; 1310 } 1311 } 1312 1313 /** 1314 * <code>create_reference</code> 1315 * <b>3.3.8.17</b> 1316 */ 1317 public org.omg.CORBA.Object create_reference(String repId) 1318 throws WrongPolicy 1319 { 1320 try { 1321 lock() ; 1322 1323 if (debug) { 1324 ORBUtility.dprint( this, "Calling create_reference(repId=" + 1325 repId + ") on poa " + this ) ; 1326 } 1327 1328 return makeObject( repId, mediator.newSystemId()) ; 1329 } finally { 1330 unlock() ; 1331 } 1332 } 1333 1334 /** 1335 * <code>create_reference_with_id</code> 1336 * <b>3.3.8.18</b> 1337 */ 1338 public org.omg.CORBA.Object 1339 create_reference_with_id(byte[] oid, String repId) 1340 { 1341 try { 1342 lock() ; 1343 1344 if (debug) { 1345 ORBUtility.dprint( this, 1346 "Calling create_reference_with_id(oid=" + 1347 oid + " repId=" + repId + ") on poa " + this ) ; 1348 } 1349 1350 // Clone the id to avoid possible errors due to aliasing 1351 // (e.g. the client passes the id in and then changes it later). 1352 byte[] idClone = (byte[])(oid.clone()) ; 1353 1354 return makeObject( repId, idClone ) ; 1355 } finally { 1356 unlock() ; 1357 } 1358 } 1359 1360 /** 1361 * <code>servant_to_id</code> 1362 * <b>3.3.8.19</b> 1363 */ 1364 public byte[] servant_to_id(Servant servant) 1365 throws ServantNotActive, WrongPolicy 1366 { 1367 try { 1368 lock() ; 1369 1370 if (debug) { 1371 ORBUtility.dprint( this, "Calling servant_to_id(servant=" + 1372 servant + ") on poa " + this ) ; 1373 } 1374 1375 return mediator.servantToId( servant ) ; 1376 } finally { 1377 unlock() ; 1378 } 1379 } 1380 1381 /** 1382 * <code>servant_to_reference</code> 1383 * <b>3.3.8.20</b> 1384 */ 1385 public org.omg.CORBA.Object servant_to_reference(Servant servant) 1386 throws ServantNotActive, WrongPolicy 1387 { 1388 try { 1389 lock() ; 1390 1391 if (debug) { 1392 ORBUtility.dprint( this, 1393 "Calling servant_to_reference(servant=" + 1394 servant + ") on poa " + this ) ; 1395 } 1396 1397 byte[] oid = mediator.servantToId(servant); 1398 String repId = servant._all_interfaces( this, oid )[0] ; 1399 return create_reference_with_id(oid, repId); 1400 } finally { 1401 unlock() ; 1402 } 1403 } 1404 1405 /** 1406 * <code>reference_to_servant</code> 1407 * <b>3.3.8.21</b> 1408 */ 1409 public Servant reference_to_servant(org.omg.CORBA.Object reference) 1410 throws ObjectNotActive, WrongPolicy, WrongAdapter 1411 { 1412 try { 1413 lock() ; 1414 1415 if (debug) { 1416 ORBUtility.dprint( this, 1417 "Calling reference_to_servant(reference=" + 1418 reference + ") on poa " + this ) ; 1419 } 1420 1421 if ( state >= STATE_DESTROYING ) { 1422 throw lifecycleWrapper().adapterDestroyed() ; 1423 } 1424 1425 // reference_to_id should throw WrongAdapter 1426 // if the objref was not created by this POA 1427 byte [] id = internalReferenceToId(reference); 1428 1429 return mediator.idToServant( id ) ; 1430 } finally { 1431 unlock() ; 1432 } 1433 } 1434 1435 /** 1436 * <code>reference_to_id</code> 1437 * <b>3.3.8.22</b> 1438 */ 1439 public byte[] reference_to_id(org.omg.CORBA.Object reference) 1440 throws WrongAdapter, WrongPolicy 1441 { 1442 try { 1443 lock() ; 1444 1445 if (debug) { 1446 ORBUtility.dprint( this, "Calling reference_to_id(reference=" + 1447 reference + ") on poa " + this ) ; 1448 } 1449 1450 if( state >= STATE_DESTROYING ) { 1451 throw lifecycleWrapper().adapterDestroyed() ; 1452 } 1453 1454 return internalReferenceToId( reference ) ; 1455 } finally { 1456 unlock() ; 1457 } 1458 } 1459 1460 /** 1461 * <code>id_to_servant</code> 1462 * <b>3.3.8.23</b> 1463 */ 1464 public Servant id_to_servant(byte[] id) 1465 throws ObjectNotActive, WrongPolicy 1466 { 1467 try { 1468 lock() ; 1469 1470 if (debug) { 1471 ORBUtility.dprint( this, "Calling id_to_servant(id=" + 1472 id + ") on poa " + this ) ; 1473 } 1474 1475 if( state >= STATE_DESTROYING ) { 1476 throw lifecycleWrapper().adapterDestroyed() ; 1477 } 1478 return mediator.idToServant( id ) ; 1479 } finally { 1480 unlock() ; 1481 } 1482 } 1483 1484 /** 1485 * <code>id_to_reference</code> 1486 * <b>3.3.8.24</b> 1487 */ 1488 public org.omg.CORBA.Object id_to_reference(byte[] id) 1489 throws ObjectNotActive, WrongPolicy 1490 1491 { 1492 try { 1493 lock() ; 1494 1495 if (debug) { 1496 ORBUtility.dprint( this, "Calling id_to_reference(id=" + 1497 id + ") on poa " + this ) ; 1498 } 1499 1500 if( state >= STATE_DESTROYING ) { 1501 throw lifecycleWrapper().adapterDestroyed() ; 1502 } 1503 1504 Servant s = mediator.idToServant( id ) ; 1505 String repId = s._all_interfaces( this, id )[0] ; 1506 return makeObject(repId, id ); 1507 } finally { 1508 unlock() ; 1509 } 1510 } 1511 1512 /** 1513 * <code>id</code> 1514 * <b>11.3.8.26 in ptc/00-08-06</b> 1515 */ 1516 public byte[] id() 1517 { 1518 try { 1519 lock() ; 1520 1521 return getAdapterId() ; 1522 } finally { 1523 unlock() ; 1524 } 1525 } 1526 1527 //*************************************************************** 1528 //Implementation of ObjectAdapter interface 1529 //*************************************************************** 1530 1531 public Policy getEffectivePolicy( int type ) 1532 { 1533 return mediator.getPolicies().get_effective_policy( type ) ; 1534 } 1535 1536 public int getManagerId() 1537 { 1538 return manager.getManagerId() ; 1539 } 1540 1541 public short getState() 1542 { 1543 return manager.getORTState() ; 1544 } 1545 1546 public String[] getInterfaces( java.lang.Object servant, byte[] objectId ) 1547 { 1548 Servant serv = (Servant)servant ; 1549 return serv._all_interfaces( this, objectId ) ; 1550 } 1551 1552 protected ObjectCopierFactory getObjectCopierFactory() 1553 { 1554 int copierId = mediator.getPolicies().getCopierId() ; 1555 CopierManager cm = getORB().getCopierManager() ; 1556 return cm.getObjectCopierFactory( copierId ) ; 1557 } 1558 1559 public void enter() throws OADestroyed 1560 { 1561 try { 1562 lock() ; 1563 1564 if (debug) { 1565 ORBUtility.dprint( this, "Calling enter on poa " + this ) ; 1566 } 1567 1568 // Avoid deadlock if this is the thread that is processing the 1569 // POA.destroy because this is the only thread that can notify 1570 // waiters on beingDestroyedCV. This can happen if an 1571 // etherealize upcall invokes a method on a colocated object 1572 // served by this POA. 1573 while ((state == STATE_DESTROYING) && 1574 (isDestroying.get() == Boolean.FALSE)) { 1575 try { 1576 beingDestroyedCV.await(); 1577 } catch (InterruptedException ex) { 1578 // NO-OP 1579 } 1580 } 1581 1582 if (!waitUntilRunning()) 1583 throw new OADestroyed() ; 1584 1585 invocationCount++; 1586 } finally { 1587 if (debug) { 1588 ORBUtility.dprint( this, "Exiting enter on poa " + this ) ; 1589 } 1590 1591 unlock() ; 1592 } 1593 1594 manager.enter(); 1595 } 1596 1597 public void exit() 1598 { 1599 try { 1600 lock() ; 1601 1602 if (debug) { 1603 ORBUtility.dprint( this, "Calling exit on poa " + this ) ; 1604 } 1605 1606 invocationCount--; 1607 1608 if ((invocationCount == 0) && (state == STATE_DESTROYING)) { 1609 invokeCV.broadcast(); 1610 } 1611 } finally { 1612 if (debug) { 1613 ORBUtility.dprint( this, "Exiting exit on poa " + this ) ; 1614 } 1615 1616 unlock() ; 1617 } 1618 1619 manager.exit(); 1620 } 1621 1622 public void getInvocationServant( OAInvocationInfo info ) 1623 { 1624 try { 1625 lock() ; 1626 1627 if (debug) { 1628 ORBUtility.dprint( this, 1629 "Calling getInvocationServant on poa " + this ) ; 1630 } 1631 1632 java.lang.Object servant = null ; 1633 1634 try { 1635 servant = mediator.getInvocationServant( info.id(), 1636 info.getOperation() ); 1637 } catch (ForwardRequest freq) { 1638 throw new ForwardException( getORB(), freq.forward_reference ) ; 1639 } 1640 1641 info.setServant( servant ) ; 1642 } finally { 1643 if (debug) { 1644 ORBUtility.dprint( this, 1645 "Exiting getInvocationServant on poa " + this ) ; 1646 } 1647 1648 unlock() ; 1649 } 1650 } 1651 1652 public org.omg.CORBA.Object getLocalServant( byte[] objectId ) 1653 { 1654 return null ; 1655 } 1656 1657 /** Called from the subcontract to let this POA cleanup after an 1658 * invocation. Note: If getServant was called, then returnServant 1659 * MUST be called, even in the case of exceptions. This may be 1660 * called multiple times for a single request. 1661 */ 1662 public void returnServant() 1663 { 1664 try { 1665 lock() ; 1666 1667 if (debug) { 1668 ORBUtility.dprint( this, 1669 "Calling returnServant on poa " + this ) ; 1670 } 1671 1672 mediator.returnServant(); 1673 } catch (Throwable thr) { 1674 if (debug) { 1675 ORBUtility.dprint( this, 1676 "Exception " + thr + " in returnServant on poa " + this ) ; 1677 } 1678 1679 if (thr instanceof Error) 1680 throw (Error)thr ; 1681 else if (thr instanceof RuntimeException) 1682 throw (RuntimeException)thr ; 1683 1684 } finally { 1685 if (debug) { 1686 ORBUtility.dprint( this, 1687 "Exiting returnServant on poa " + this ) ; 1688 } 1689 1690 unlock() ; 1691 } 1692 } 1693 }