POAImpl.java revision 667:d0315150c39d
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 26package com.sun.corba.se.impl.oa.poa; 27 28import java.util.Collection ; 29import java.util.Set ; 30import java.util.HashSet ; 31import java.util.Map ; 32import java.util.HashMap ; 33import java.util.Iterator ; 34 35import org.omg.CORBA.Policy ; 36import org.omg.CORBA.SystemException ; 37 38import org.omg.PortableServer.POA ; 39import org.omg.PortableServer.Servant ; 40import org.omg.PortableServer.POAManager ; 41import org.omg.PortableServer.AdapterActivator ; 42import org.omg.PortableServer.ServantManager ; 43import org.omg.PortableServer.ForwardRequest ; 44import org.omg.PortableServer.ThreadPolicy; 45import org.omg.PortableServer.LifespanPolicy; 46import org.omg.PortableServer.IdUniquenessPolicy; 47import org.omg.PortableServer.IdAssignmentPolicy; 48import org.omg.PortableServer.ImplicitActivationPolicy; 49import org.omg.PortableServer.ServantRetentionPolicy; 50import org.omg.PortableServer.RequestProcessingPolicy; 51import org.omg.PortableServer.ThreadPolicyValue ; 52import org.omg.PortableServer.LifespanPolicyValue ; 53import org.omg.PortableServer.IdUniquenessPolicyValue ; 54import org.omg.PortableServer.IdAssignmentPolicyValue ; 55import org.omg.PortableServer.ImplicitActivationPolicyValue ; 56import org.omg.PortableServer.ServantRetentionPolicyValue ; 57import org.omg.PortableServer.RequestProcessingPolicyValue ; 58import org.omg.PortableServer.POAPackage.AdapterAlreadyExists ; 59import org.omg.PortableServer.POAPackage.AdapterNonExistent ; 60import org.omg.PortableServer.POAPackage.InvalidPolicy ; 61import org.omg.PortableServer.POAPackage.WrongPolicy ; 62import org.omg.PortableServer.POAPackage.WrongAdapter ; 63import org.omg.PortableServer.POAPackage.NoServant ; 64import org.omg.PortableServer.POAPackage.ServantAlreadyActive ; 65import org.omg.PortableServer.POAPackage.ObjectAlreadyActive ; 66import org.omg.PortableServer.POAPackage.ServantNotActive ; 67import org.omg.PortableServer.POAPackage.ObjectNotActive ; 68 69import org.omg.PortableInterceptor.ObjectReferenceFactory ; 70import org.omg.PortableInterceptor.ObjectReferenceTemplate ; 71import org.omg.PortableInterceptor.NON_EXISTENT ; 72 73import org.omg.IOP.TAG_INTERNET_IOP ; 74 75import com.sun.corba.se.spi.copyobject.CopierManager ; 76import com.sun.corba.se.spi.copyobject.ObjectCopier ; 77import com.sun.corba.se.spi.copyobject.ObjectCopierFactory ; 78import com.sun.corba.se.spi.oa.OADestroyed ; 79import com.sun.corba.se.spi.oa.OAInvocationInfo ; 80import com.sun.corba.se.spi.oa.ObjectAdapter ; 81import com.sun.corba.se.spi.oa.ObjectAdapterBase ; 82import com.sun.corba.se.spi.oa.ObjectAdapterFactory ; 83import com.sun.corba.se.spi.ior.ObjectKeyTemplate ; 84import com.sun.corba.se.spi.ior.ObjectId ; 85import com.sun.corba.se.spi.ior.ObjectAdapterId ; 86import com.sun.corba.se.spi.ior.IOR ; 87import com.sun.corba.se.spi.ior.IORFactories ; 88import com.sun.corba.se.spi.ior.IORTemplate ; 89import com.sun.corba.se.spi.ior.IORTemplateList ; 90import com.sun.corba.se.spi.ior.TaggedProfile ; 91import com.sun.corba.se.spi.ior.iiop.IIOPProfile ; 92import com.sun.corba.se.spi.ior.iiop.IIOPAddress ; 93import com.sun.corba.se.spi.ior.iiop.IIOPFactories ; 94import com.sun.corba.se.spi.orb.ORB ; 95import com.sun.corba.se.spi.protocol.ForwardException ; 96import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor; 97 98import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ; 99import com.sun.corba.se.impl.ior.ObjectAdapterIdArray ; 100import com.sun.corba.se.impl.orbutil.ORBUtility; 101import com.sun.corba.se.impl.orbutil.ORBConstants; 102import com.sun.corba.se.impl.orbutil.concurrent.Sync ; 103import com.sun.corba.se.impl.orbutil.concurrent.SyncUtil ; 104import com.sun.corba.se.impl.orbutil.concurrent.ReentrantMutex ; 105import com.sun.corba.se.impl.orbutil.concurrent.CondVar ; 106import com.sun.corba.se.impl.transport.ManagedLocalsThread; 107 108/** 109 * POAImpl is the implementation of the Portable Object Adapter. It 110 * contains an implementation of the POA interfaces specified in 111 * COBRA 2.3.1 chapter 11 (formal/99-10-07). This implementation 112 * is moving to comply with CORBA 3.0 due to the many clarifications 113 * that have been made to the POA semantics since CORBA 2.3.1. 114 * Specific comments have been added where 3.0 applies, but note that 115 * we do not have the new 3.0 APIs yet. 116 */ 117public class POAImpl extends ObjectAdapterBase implements POA 118{ 119 private boolean debug ; 120 121 /* POA creation takes place in 2 stages: first, the POAImpl constructor is 122 called, then the initialize method is called. This separation is 123 needed because an AdapterActivator does not know the POAManager or 124 the policies when 125 the unknown_adapter method is invoked. However, the POA must be created 126 before the unknown_adapter method is invoked, so that the parent knows 127 when concurrent attempts are made to create the same POA. 128 Calling the POAImpl constructor results in a new POA in state STATE_START. 129 Calling initialize( POAManager, Policies ) results in state STATE_RUN. 130 Calling destroy results in STATE_DESTROY, which marks the beginning of 131 POA destruction. 132 */ 133 134 // Notes on concurrency. 135 // The POA requires careful design for concurrency management to correctly 136 // implement the specification and avoid deadlocks. The order of acquiring 137 // locks must respect the following locking hierarchy: 138 // 139 // 1. Lock POAs before POAManagers 140 // 2. Lock a POA before locking its child POA 141 // 142 // Also note that there are 3 separate conditions on which threads may wait 143 // in the POA, as defined by invokeCV, beingDestroyedCV, and 144 // adapterActivatorCV. This means that (for this reason as well as others) 145 // we cannot simply use the standard Java synchronized primitive. 146 // This implementation uses a modified version of Doug Lea's 147 // util.concurrent (version 1.3.0) that supports reentrant 148 // mutexes to handle the locking. This will all be replaced by the new JSR 149 // 166 concurrency primitives in J2SE 1.5 and later once the ORB moves to 150 // J2SE 1.5. 151 152 // POA state constants 153 // 154 // Note that ordering is important here: we must have the state defined in 155 // this order so that ordered comparison is possible. 156 // DO NOT CHANGE THE VALUES OF THE STATE CONSTANTS!!! In particular, the 157 // initialization related states must be lower than STATE_RUN. 158 // 159 // POA is created in STATE_START 160 // 161 // Valid state transitions: 162 // 163 // START to INIT after find_POA constructor call 164 // START to RUN after initialize completes 165 // INIT to INIT_DONE after initialize completes 166 // INIT to DESTROYED after failed unknown_adapter 167 // INIT_DONE to RUN after successful unknown_adapter 168 // STATE_RUN to STATE_DESTROYING after start of destruction 169 // STATE_DESTROYING to STATE_DESTROYED after destruction completes. 170 171 private static final int STATE_START = 0 ; // constructor complete 172 private static final int STATE_INIT = 1 ; // waiting for adapter activator 173 private static final int STATE_INIT_DONE = 2 ; // adapter activator called create_POA 174 private static final int STATE_RUN = 3 ; // initialized and running 175 private static final int STATE_DESTROYING = 4 ; // being destroyed 176 private static final int STATE_DESTROYED = 5 ; // destruction complete 177 178 private String stateToString() 179 { 180 switch (state) { 181 case STATE_START : 182 return "START" ; 183 case STATE_INIT : 184 return "INIT" ; 185 case STATE_INIT_DONE : 186 return "INIT_DONE" ; 187 case STATE_RUN : 188 return "RUN" ; 189 case STATE_DESTROYING : 190 return "DESTROYING" ; 191 case STATE_DESTROYED : 192 return "DESTROYED" ; 193 default : 194 return "UNKNOWN(" + state + ")" ; 195 } 196 } 197 198 // Current state of the POA 199 private int state ; 200 201 // The POA request handler that performs all policy specific operations 202 // Note that POAImpl handles all synchronization, so mediator is (mostly) 203 // unsynchronized. 204 private POAPolicyMediator mediator; 205 206 // Representation of object adapter ID 207 private int numLevels; // counts depth of tree. Root = 1. 208 private ObjectAdapterId poaId ; // the actual object adapter ID for this POA 209 private String name; // the name of this POA 210 211 private POAManagerImpl manager; // This POA's POAManager 212 private int uniquePOAId ; // ID for this POA that is unique relative 213 // to the POAFactory, which has the same 214 // lifetime as the ORB. 215 private POAImpl parent; // The POA that created this POA. 216 private Map children; // Map from name to POA of POAs created by 217 // this POA. 218 219 private AdapterActivator activator; 220 private int invocationCount ; // pending invocations on this POA. 221 222 // Data used to control POA concurrency 223 // XXX revisit for JSR 166 224 225 // Master lock for all POA synchronization. See lock and unlock. 226 // package private for access by AOMEntry. 227 Sync poaMutex ; 228 229 // Wait on this CV for AdapterActivator upcalls to complete 230 private CondVar adapterActivatorCV ; 231 232 // Wait on this CV for all active invocations to complete 233 private CondVar invokeCV ; 234 235 // Wait on this CV for the destroy method to complete doing its work 236 private CondVar beingDestroyedCV ; 237 238 // thread local variable to store a boolean to detect deadlock in 239 // POA.destroy(). 240 protected ThreadLocal isDestroying ; 241 242 // This includes the most important information for debugging 243 // POA problems. 244 public String toString() 245 { 246 return "POA[" + poaId.toString() + 247 ", uniquePOAId=" + uniquePOAId + 248 ", state=" + stateToString() + 249 ", invocationCount=" + invocationCount + "]" ; 250 } 251 252 // package private for mediator implementations. 253 boolean getDebug() 254 { 255 return debug ; 256 } 257 258 // package private for access to servant to POA map 259 static POAFactory getPOAFactory( ORB orb ) 260 { 261 return (POAFactory)orb.getRequestDispatcherRegistry(). 262 getObjectAdapterFactory( ORBConstants.TRANSIENT_SCID ) ; 263 } 264 265 // package private so that POAFactory can access it. 266 static POAImpl makeRootPOA( ORB orb ) 267 { 268 POAManagerImpl poaManager = new POAManagerImpl( getPOAFactory( orb ), 269 orb.getPIHandler() ) ; 270 271 POAImpl result = new POAImpl( ORBConstants.ROOT_POA_NAME, 272 null, orb, STATE_START ) ; 273 result.initialize( poaManager, Policies.rootPOAPolicies ) ; 274 275 return result ; 276 } 277 278 // package private so that POAPolicyMediatorBase can access it. 279 int getPOAId() 280 { 281 return uniquePOAId ; 282 } 283 284 285 // package private so that POAPolicyMediator can access it. 286 void lock() 287 { 288 SyncUtil.acquire( poaMutex ) ; 289 290 if (debug) { 291 ORBUtility.dprint( this, "LOCKED poa " + this ) ; 292 } 293 } 294 295 // package private so that POAPolicyMediator can access it. 296 void unlock() 297 { 298 if (debug) { 299 ORBUtility.dprint( this, "UNLOCKED poa " + this ) ; 300 } 301 302 poaMutex.release() ; 303 } 304 305 // package private so that DelegateImpl can access it. 306 Policies getPolicies() 307 { 308 return mediator.getPolicies() ; 309 } 310 311 // Note that the parent POA must be locked when this constructor is called. 312 private POAImpl( String name, POAImpl parent, ORB orb, int initialState ) 313 { 314 super( orb ) ; 315 316 debug = orb.poaDebugFlag ; 317 318 if (debug) { 319 ORBUtility.dprint( this, "Creating POA with name=" + name + 320 " parent=" + parent ) ; 321 } 322 323 this.state = initialState ; 324 this.name = name ; 325 this.parent = parent; 326 children = new HashMap(); 327 activator = null ; 328 329 // This was done in initialize, but I moved it here 330 // to get better searchability when tracing. 331 uniquePOAId = getPOAFactory( orb ).newPOAId() ; 332 333 if (parent == null) { 334 // This is the root POA, which counts as 1 level 335 numLevels = 1 ; 336 } else { 337 // My level is one more than that of my parent 338 numLevels = parent.numLevels + 1 ; 339 340 parent.children.put(name, this); 341 } 342 343 // Get an array of all of the POA names in order to 344 // create the poaid. 345 String[] names = new String[ numLevels ] ; 346 POAImpl poaImpl = this ; 347 int ctr = numLevels - 1 ; 348 while (poaImpl != null) { 349 names[ctr--] = poaImpl.name ; 350 poaImpl = poaImpl.parent ; 351 } 352 353 poaId = new ObjectAdapterIdArray( names ) ; 354 355 invocationCount = 0; 356 357 poaMutex = new ReentrantMutex( orb.poaConcurrencyDebugFlag ) ; 358 359 adapterActivatorCV = new CondVar( poaMutex, 360 orb.poaConcurrencyDebugFlag ) ; 361 invokeCV = new CondVar( poaMutex, 362 orb.poaConcurrencyDebugFlag ) ; 363 beingDestroyedCV = new CondVar( poaMutex, 364 orb.poaConcurrencyDebugFlag ) ; 365 366 isDestroying = new ThreadLocal () { 367 protected java.lang.Object initialValue() { 368 return Boolean.FALSE; 369 } 370 }; 371 } 372 373 // The POA lock must be held when this method is called. 374 private void initialize( POAManagerImpl manager, Policies policies ) 375 { 376 if (debug) { 377 ORBUtility.dprint( this, "Initializing poa " + this + 378 " with POAManager=" + manager + " policies=" + policies ) ; 379 } 380 381 this.manager = manager; 382 manager.addPOA(this); 383 384 mediator = POAPolicyMediatorFactory.create( policies, this ) ; 385 386 // Construct the object key template 387 int serverid = mediator.getServerId() ; 388 int scid = mediator.getScid() ; 389 String orbId = getORB().getORBData().getORBId(); 390 391 ObjectKeyTemplate oktemp = new POAObjectKeyTemplate( getORB(), 392 scid, serverid, orbId, poaId ) ; 393 394 if (debug) { 395 ORBUtility.dprint( this, "Initializing poa: oktemp=" + oktemp ) ; 396 } 397 398 // Note that parent == null iff this is the root POA. 399 // This was used to avoid executing interceptors on the RootPOA. 400 // That is no longer necessary. 401 boolean objectAdapterCreated = true; // parent != null ; 402 403 // XXX extract codebase from policies and pass into initializeTemplate 404 // after the codebase policy change is finalized. 405 initializeTemplate( oktemp, objectAdapterCreated, 406 policies, 407 null, // codebase 408 null, // manager id 409 oktemp.getObjectAdapterId() 410 ) ; 411 412 if (state == STATE_START) 413 state = STATE_RUN ; 414 else if (state == STATE_INIT) 415 state = STATE_INIT_DONE ; 416 else 417 throw lifecycleWrapper().illegalPoaStateTrans() ; 418 } 419 420 // The poaMutex must be held when this method is called 421 private boolean waitUntilRunning() 422 { 423 if (debug) { 424 ORBUtility.dprint( this, 425 "Calling waitUntilRunning on poa " + this ) ; 426 } 427 428 while (state < STATE_RUN) { 429 try { 430 adapterActivatorCV.await() ; 431 } catch (InterruptedException exc) { 432 // NO-OP 433 } 434 } 435 436 if (debug) { 437 ORBUtility.dprint( this, 438 "Exiting waitUntilRunning on poa " + this ) ; 439 } 440 441 // Note that a POA could be destroyed while in STATE_INIT due to a 442 // failure in the AdapterActivator upcall. 443 return (state == STATE_RUN) ; 444 } 445 446 // This method checks that the AdapterActivator finished the 447 // initialization of a POA activated in find_POA. This is 448 // determined by checking the state of the POA. If the state is 449 // STATE_INIT, the AdapterActivator did not complete the 450 // inialization. In this case, we destroy the POA that was 451 // partially created and return false. Otherwise, we return true. 452 // In any case, we must wake up all threads waiting for the adapter 453 // activator, either to continue their invocations, or to return 454 // errors to their client. 455 // 456 // The poaMutex must NOT be held when this method is called. 457 private boolean destroyIfNotInitDone() 458 { 459 try { 460 lock() ; 461 462 if (debug) { 463 ORBUtility.dprint( this, 464 "Calling destroyIfNotInitDone on poa " + this ) ; 465 } 466 467 boolean success = (state == STATE_INIT_DONE) ; 468 469 if (success) 470 state = STATE_RUN ; 471 else { 472 // Don't just use destroy, because the check for 473 // deadlock is too general, and can prevent this from 474 // functioning properly. 475 DestroyThread destroyer = new DestroyThread( false, debug ); 476 destroyer.doIt( this, true ) ; 477 } 478 479 return success ; 480 } finally { 481 adapterActivatorCV.broadcast() ; 482 483 if (debug) { 484 ORBUtility.dprint( this, 485 "Exiting destroyIfNotInitDone on poa " + this ) ; 486 } 487 488 unlock() ; 489 } 490 } 491 492 private byte[] internalReferenceToId( 493 org.omg.CORBA.Object reference ) throws WrongAdapter 494 { 495 IOR ior = ORBUtility.getIOR( reference ) ; 496 IORTemplateList thisTemplate = ior.getIORTemplates() ; 497 498 ObjectReferenceFactory orf = getCurrentFactory() ; 499 IORTemplateList poaTemplate = 500 IORFactories.getIORTemplateList( orf ) ; 501 502 if (!poaTemplate.isEquivalent( thisTemplate )) 503 throw new WrongAdapter(); 504 505 // Extract the ObjectId from the first TaggedProfile in the IOR. 506 // If ior was created in this POA, the same ID was used for 507 // every profile through the profile templates in the currentFactory, 508 // so we will get the same result from any profile. 509 Iterator iter = ior.iterator() ; 510 if (!iter.hasNext()) 511 throw iorWrapper().noProfilesInIor() ; 512 TaggedProfile prof = (TaggedProfile)(iter.next()) ; 513 ObjectId oid = prof.getObjectId() ; 514 515 return oid.getId(); 516 } 517 518 // Converted from anonymous class to local class 519 // so that we can call performDestroy() directly. 520 static class DestroyThread extends ManagedLocalsThread { 521 private boolean wait ; 522 private boolean etherealize ; 523 private boolean debug ; 524 private POAImpl thePoa ; 525 526 public DestroyThread( boolean etherealize, boolean debug ) 527 { 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} 1694