Class POAManagerImpl

java.lang.Object
org.omg.CORBA.LocalObject
com.sun.corba.ee.impl.oa.poa.POAManagerImpl
All Implemented Interfaces:
Serializable, Object, IDLEntity, POAManager, POAManagerOperations

@ManagedObject @Description("A POAManager which controls invocations of its POAs") public class POAManagerImpl extends LocalObject implements POAManager
POAManagerImpl is the implementation of the POAManager interface. Its public methods are activate(), hold_requests(), discard_requests() and deactivate().
See Also:
  • Field Details

    • wrapper

      private static final POASystemException wrapper
    • serialVersionUID

      private static final long serialVersionUID
      See Also:
    • factory

      private final POAFactory factory
    • pihandler

      private final PIHandler pihandler
    • myId

      private final int myId
    • stateLock

      private final ReentrantReadWriteLock stateLock
    • stateCV

      private final Condition stateCV
    • state

      private State state
    • poas

      private Set<POAImpl> poas
    • nInvocations

      private AtomicInteger nInvocations
    • nWaiters

      private AtomicInteger nWaiters
    • explicitStateChange

      private volatile boolean explicitStateChange
    • activeManagers

      private static ThreadLocal<org.glassfish.pfl.basic.contain.MultiSet<POAManagerImpl>> activeManagers
      activeManagers is the set of POAManagerImpls for which a thread has called enter without exit 1 or more times. Once a thread has entered a POAManager, it must be able to re-enter the POAManager, even if the manager is HOLDING, because state transitions can be deferred until all threads have completed execution and called exit(). Without this change, one thread can be blocked on the state change method, and another thread that has entered the POAManager once can be blocked from re-entry on a nested co-located call. This leads to a permanent deadlock between the two threads. See Bug 6586417. To avoid this, we create a set of active managers, and record which managers a particular thread is using. A thread may re-enter any manager in HOLDING state once it has entered it for the first time. Note that POAManagerImpl uses the default equals and hashCode methods inherited from Object. This is fine, because two distinct POAManagerImpl instances always represent distinct POAManagerImpls. This is only a partial solution to the problem, but it should be sufficient for the app server, because all EJBs in the app server share the same POAManager. The problem in general is that state changes between multiple POAManager and invocation threads that make co-located calls to different POAManagers can still deadlock. This problem requires a different solution, because the hold_requests method may have already returned when the active thread needs to enter the holding POAManager, so we can't just let the thread in. I think in this case we need to reject the request because it may cause a deadlock. So, checkState needs to throw a TRANSIENT exception if it finds that the thread is already active in one or more POAManagers, AND it tries to enter a new POAManager. Such exceptions should be re-tried by the client, and will succeed after the holding POAManagers have been resumed. Another possible route to fix the app server bug (more globally) is to have the RFM suspend method use discard instead of hold. This may be better in some ways, but early tests with that approach led to some problems (which I can't recall right now). I suspect the issues may have been related to problems with the client-side retry logic, but those problems have now been fixed. In any case, we need to fix the POAManager issues.
  • Constructor Details

  • Method Details

    • stateToString

      private String stateToString(State state)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • getManagedPOAs

      @ManagedAttribute @Description("The set of POAs managed by this POAManager") Set<POAImpl> getManagedPOAs()
    • numberOfInvocations

      @ManagedAttribute @Description("Number of active invocations executing in this POAManager") public int numberOfInvocations()
    • numberOfWaiters

      @ManagedAttribute @Description("Number of threads waiting for invocations to complete in this POAManager") public int numberOfWaiters()
    • displayState

      @ManagedAttribute @Description("The current state of this POAManager") public String displayState()
    • getFactory

      @ManagedAttribute @Description("The POAFactory that manages this POAManager") POAFactory getFactory()
    • getPIHandler

      PIHandler getPIHandler()
    • numWaitersStart

      @InfoMethod private void numWaitersStart(int value)
    • numWaitersEnd

      @InfoMethod private void numWaitersEnd(int value)
    • countedWait

      private void countedWait()
    • nWaiters

      @InfoMethod private void nWaiters(int value)
    • notifyWaiters

      private void notifyWaiters()
    • getManagerId

      @ManagedAttribute @NameValue @Description("The ID of this POAManager") public int getManagerId()
    • addPOA

      void addPOA(POAImpl poa)
    • removePOA

      void removePOA(POAImpl poa)
    • getORTState

      @ManagedAttribute @Description("The ObjectReferenceTemplate state of this POAManager") public short getORTState()
    • activate

      @ManagedOperation @Description("Make this POAManager active, so it can handle new requests") public void activate() throws AdapterInactive
      activate Spec: pages 3-14 thru 3-18
      Specified by:
      activate in interface POAManagerOperations
      Throws:
      AdapterInactive - is raised if the operation is invoked on the POAManager in inactive state.
    • hold_requests

      @ManagedOperation @Description("Hold all requests to this POAManager") public void hold_requests(boolean wait_for_completion) throws AdapterInactive
      hold_requests Spec: pages 3-14 thru 3-18
      Specified by:
      hold_requests in interface POAManagerOperations
      Parameters:
      wait_for_completion - if FALSE, the operation returns immediately after changing state. If TRUE, it waits for all active requests to complete.
      Throws:
      AdapterInactive - is raised if the operation is invoked on the POAManager in inactive state.
    • discard_requests

      @ManagedOperation @ParameterNames("waitForCompletion") @Description("Make this POAManager discard all incoming requests") public void discard_requests(boolean wait_for_completion) throws AdapterInactive
      discard_requests Spec: pages 3-14 thru 3-18
      Specified by:
      discard_requests in interface POAManagerOperations
      Parameters:
      wait_for_completion - if FALSE, the operation returns immediately after changing state. If TRUE, it waits for all active requests to complete.
      Throws:
      AdapterInactive - is raised if the operation is invoked on the POAManager in inactive state.
    • deactivate

      public void deactivate(boolean etherealize_objects, boolean wait_for_completion) throws AdapterInactive
      deactivate Spec: pages 3-14 thru 3-18 Note: INACTIVE is a permanent state.
      Specified by:
      deactivate in interface POAManagerOperations
      Parameters:
      etherealize_objects - a flag to indicate whether to invoke the etherealize operation of the associated servant manager for all active objects.
      wait_for_completion - if FALSE, the operation returns immediately after changing state. If TRUE, it waits for all active requests to complete.
      Throws:
      AdapterInactive - is raised if the operation is invoked on the POAManager in inactive state.
    • get_state

      public State get_state()
      Added according to the spec CORBA V2.3; this returns the state of the POAManager
      Specified by:
      get_state in interface POAManagerOperations
      Returns:
      the state of the manager
    • activeManagers

      @InfoMethod private void activeManagers(org.glassfish.pfl.basic.contain.MultiSet<POAManagerImpl> am)
      The following methods are used on the invocation path.
    • alreadyActive

      @InfoMethod private void alreadyActive(POAManagerImpl pm)
    • activeInDifferentPoaManager

      @InfoMethod private void activeInDifferentPoaManager()
    • checkState

      private void checkState()
    • addingThreadToActiveManagers

      @InfoMethod private void addingThreadToActiveManagers(POAManagerImpl pmi)
    • removingThreadFromActiveManagers

      @InfoMethod private void removingThreadFromActiveManagers(POAManagerImpl pmi)
    • enter

      void enter()
    • exit

      void exit()
    • implicitActivation

      public void implicitActivation()
      Activate the POAManager if no explicit state change has ever been previously invoked.