Package com.sun.corba.ee.impl.oa.poa
Class POAManagerImpl
- java.lang.Object
-
- org.omg.CORBA.LocalObject
-
- com.sun.corba.ee.impl.oa.poa.POAManagerImpl
-
- All Implemented Interfaces:
java.io.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:
- Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
POAManagerImpl.POAManagerDeactivator
-
Field Summary
Fields Modifier and Type Field Description private static java.lang.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.private boolean
explicitStateChange
private POAFactory
factory
private int
myId
private java.util.concurrent.atomic.AtomicInteger
nInvocations
private java.util.concurrent.atomic.AtomicInteger
nWaiters
private PIHandler
pihandler
private java.util.Set<POAImpl>
poas
private static long
serialVersionUID
private State
state
private java.util.concurrent.locks.Condition
stateCV
private java.util.concurrent.locks.ReentrantReadWriteLock
stateLock
private static POASystemException
wrapper
-
Constructor Summary
Constructors Constructor Description POAManagerImpl(POAFactory factory, PIHandler pih)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
activate()
activate
Spec: pages 3-14 thru 3-18private void
activeInDifferentPoaManager()
private void
activeManagers(org.glassfish.pfl.basic.contain.MultiSet<POAManagerImpl> am)
The following methods are used on the invocation path.private void
addingThreadToActiveManagers(POAManagerImpl pmi)
(package private) void
addPOA(POAImpl poa)
private void
alreadyActive(POAManagerImpl pm)
private void
checkState()
private void
countedWait()
void
deactivate(boolean etherealize_objects, boolean wait_for_completion)
deactivate
Spec: pages 3-14 thru 3-18 Note: INACTIVE is a permanent state.void
discard_requests(boolean wait_for_completion)
discard_requests
Spec: pages 3-14 thru 3-18java.lang.String
displayState()
(package private) void
enter()
boolean
equals(java.lang.Object obj)
(package private) void
exit()
State
get_state()
Added according to the spec CORBA V2.3; this returns the state of the POAManager(package private) POAFactory
getFactory()
(package private) java.util.Set<POAImpl>
getManagedPOAs()
int
getManagerId()
short
getORTState()
(package private) PIHandler
getPIHandler()
int
hashCode()
void
hold_requests(boolean wait_for_completion)
hold_requests
Spec: pages 3-14 thru 3-18void
implicitActivation()
Activate the POAManager if no explicit state change has ever been previously invoked.private void
notifyWaiters()
int
numberOfInvocations()
int
numberOfWaiters()
private void
numWaitersEnd(int value)
private void
numWaitersStart(int value)
private void
nWaiters(int value)
(package private) void
removePOA(POAImpl poa)
private void
removingThreadFromActiveManagers(POAManagerImpl pmi)
private java.lang.String
stateToString(State state)
java.lang.String
toString()
-
Methods inherited from class org.omg.CORBA.LocalObject
_create_request, _create_request, _duplicate, _get_domain_managers, _get_interface, _get_interface_def, _get_policy, _hash, _invoke, _is_a, _is_equivalent, _is_local, _non_existent, _orb, _release, _releaseReply, _request, _request, _servant_postinvoke, _servant_preinvoke, _set_policy_override, validate_connection
-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.omg.CORBA.Object
_create_request, _create_request, _duplicate, _get_domain_managers, _get_interface_def, _get_policy, _hash, _is_a, _is_equivalent, _non_existent, _release, _request, _set_policy_override
-
-
-
-
Field Detail
-
wrapper
private static final POASystemException wrapper
-
serialVersionUID
private static final long serialVersionUID
- See Also:
- Constant Field Values
-
factory
private final POAFactory factory
-
pihandler
private final PIHandler pihandler
-
myId
private final int myId
-
stateLock
private final java.util.concurrent.locks.ReentrantReadWriteLock stateLock
-
stateCV
private final java.util.concurrent.locks.Condition stateCV
-
state
private State state
-
poas
private java.util.Set<POAImpl> poas
-
nInvocations
private java.util.concurrent.atomic.AtomicInteger nInvocations
-
nWaiters
private java.util.concurrent.atomic.AtomicInteger nWaiters
-
explicitStateChange
private volatile boolean explicitStateChange
-
activeManagers
private static java.lang.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 Detail
-
POAManagerImpl
POAManagerImpl(POAFactory factory, PIHandler pih)
-
-
Method Detail
-
stateToString
private java.lang.String stateToString(State state)
-
hashCode
public int hashCode()
- Overrides:
hashCode
in classjava.lang.Object
-
equals
public boolean equals(java.lang.Object obj)
- Overrides:
equals
in classjava.lang.Object
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
getManagedPOAs
@ManagedAttribute @Description("The set of POAs managed by this POAManager") java.util.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 java.lang.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 interfacePOAManagerOperations
- 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 interfacePOAManagerOperations
- 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 interfacePOAManagerOperations
- 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 interfacePOAManagerOperations
- 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 interfacePOAManagerOperations
- 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.
-
-