if ((sc == null) || (sc.getState() == BeanState.DESTROYED)) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Context already destroyed");
}
// EJB2.0 section 7.6
throw new NoSuchObjectLocalException("The EJB does not exist."
+ " session-key: " + sessionKey);
}
MethodLockInfo lockInfo = inv.invocationInfo.methodLockInfo;
boolean allowSerializedAccess =
(lockInfo == null) || (lockInfo.getTimeout() != CONCURRENCY_NOT_ALLOWED);
if( allowSerializedAccess ) {
boolean blockWithTimeout =
(lockInfo != null) && (lockInfo.getTimeout() != BLOCK_INDEFINITELY);
if( blockWithTimeout ) {
try {
boolean acquired = sc.getStatefulWriteLock().tryLock(lockInfo.getTimeout(),
lockInfo.getTimeUnit());
if( !acquired ) {
String msg = "Serialized access attempt on method " + inv.beanMethod +
" for ejb " + ejbDescriptor.getName() + " timed out after " +
+ lockInfo.getTimeout() + " " + lockInfo.getTimeUnit();
throw new ConcurrentAccessTimeoutException(msg);
}
} catch(InterruptedException ie) {
String msg = "Serialized access attempt on method " + inv.beanMethod +
" for ejb " + ejbDescriptor.getName() + " was interrupted within " +
+ lockInfo.getTimeout() + " " + lockInfo.getTimeUnit();
ConcurrentAccessException cae = new ConcurrentAccessTimeoutException(msg);
cae.initCause(ie);
throw cae;
}
} else {
sc.getStatefulWriteLock().lock();
}
// Explicitly set state to track that we're holding the lock for this invocation.
// No matter what we need to ensure that the lock is released. In some
// cases releaseContext() isn't called so for safety we'll have more than one
// place that can potentially release the lock. The invocation state will ensure
// we don't accidently unlock too many times.
inv.setHoldingSFSBSerializedLock(true);
}
SessionContextImpl context = null;
try {
synchronized (sc) {
SessionContextImpl newSC = sc;
if (sc.getState() == BeanState.PASSIVATED) {
// This is possible if the EJB was passivated after
// the last lookupEJB. Try to activate it again.
newSC = (SessionContextImpl) sessionBeanCache.lookupEJB(
sessionKey, this, ejbo);
if (newSC == null) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Context does not exist");
}
// EJB2.0 section 7.6
throw new NoSuchObjectLocalException(
"The EJB does not exist. key: " + sessionKey);
}
// Swap any stateful lock that was set on the original sc
newSC.setStatefulWriteLock(sc);
}
// acquire the lock again, in case a new sc was returned.
synchronized (newSC) { //newSC could be same as sc
// Check & set the state of the EJB
if (newSC.getState() == BeanState.DESTROYED) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Got destroyed context");
}
throw new NoSuchObjectLocalException
("The EJB does not exist. session-key: " + sessionKey);
} else if (newSC.getState() == BeanState.INVOKING) {
handleConcurrentInvocation(allowSerializedAccess, inv, newSC, sessionKey);
}
if (newSC.getState() == BeanState.READY) {