/*
* @(#)AOMEntry.java 1.28 03/12/19
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.corba.se.impl.oa.poa ;
import org.omg.CORBA.INTERNAL ;
import com.sun.corba.se.spi.orb.ORB ;
import com.sun.corba.se.spi.orbutil.fsm.Action ;
import com.sun.corba.se.spi.orbutil.fsm.ActionBase ;
import com.sun.corba.se.spi.orbutil.fsm.Guard ;
import com.sun.corba.se.spi.orbutil.fsm.GuardBase ;
import com.sun.corba.se.spi.orbutil.fsm.State ;
import com.sun.corba.se.spi.orbutil.fsm.StateImpl ;
import com.sun.corba.se.spi.orbutil.fsm.Input ;
import com.sun.corba.se.spi.orbutil.fsm.InputImpl ;
import com.sun.corba.se.spi.orbutil.fsm.FSM ;
import com.sun.corba.se.spi.orbutil.fsm.FSMImpl ;
import com.sun.corba.se.spi.orbutil.fsm.StateEngine ;
import com.sun.corba.se.spi.orbutil.fsm.StateEngineFactory ;
import com.sun.corba.se.impl.orbutil.concurrent.Mutex ;
import com.sun.corba.se.impl.orbutil.concurrent.CondVar ;
/** AOMEntry represents a Servant or potential Servant in the ActiveObjectMap.
* It may be in several states to allow for long incarnate or etherealize operations.
* The methods on this class mostly represent input symbols to the state machine
* that controls the lifecycle of the entry. A library is used to build the state
* machine rather than the more usual state pattern so that the state machine
* transitions are explicitly visible.
*/
public class AOMEntry extends FSMImpl {
private final Thread[] etherealizer ; // The actual etherealize operation
// for this entry. It is
// represented as a Thread because
// the POA.deactivate_object never
// waits for the completion.
private final int[] counter ; // single element holder for counter
// accessed in actions
private final CondVar wait ; // accessed in actions
final POAImpl poa ;
public static final State INVALID = new StateImpl( "Invalid" ) ;
public static final State INCARN = new StateImpl( "Incarnating" ) {
public void postAction( FSM fsm ) {
AOMEntry entry = (AOMEntry)fsm ;
entry.wait.broadcast() ;
}
};
public static final State VALID = new StateImpl( "Valid" ) ;
public static final State ETHP = new StateImpl( "EtherealizePending" ) ;
public static final State ETH = new StateImpl( "Etherealizing" ) {
public void preAction( FSM fsm ) {
AOMEntry entry = (AOMEntry)fsm ;
Thread etherealizer = entry.etherealizer[0] ;
if (etherealizer != null)
etherealizer.start() ;
}
public void postAction( FSM fsm ) {
AOMEntry entry = (AOMEntry)fsm ;
entry.wait.broadcast() ;
}
};
public static final State DESTROYED = new StateImpl( "Destroyed" ) ;
static final Input START_ETH = new InputImpl( "startEtherealize" ) ;
static final Input ETH_DONE = new InputImpl( "etherealizeDone" ) ;
static final Input INC_DONE = new InputImpl( "incarnateDone" ) ;
static final Input INC_FAIL = new InputImpl( "incarnateFailure" ) ;
static final Input ACTIVATE = new InputImpl( "activateObject" ) ;
static final Input ENTER = new InputImpl( "enter" ) ;
static final Input EXIT = new InputImpl( "exit" ) ;
private static Action incrementAction = new ActionBase( "increment" ) {
public void doIt( FSM fsm, Input in ) {
AOMEntry entry = (AOMEntry)fsm ;
entry.counter[0]++ ;
}
} ;
private static Action decrementAction = new ActionBase( "decrement" ) {
public void doIt( FSM fsm, Input in ) {
AOMEntry entry = (AOMEntry)fsm ;
if (entry.counter[0] > 0)
entry.counter[0]-- ;
else
throw entry.poa.lifecycleWrapper().aomEntryDecZero() ;
}
} ;
private static Action throwIllegalStateExceptionAction = new ActionBase(
"throwIllegalStateException" ) {
public void doIt( FSM fsm, Input in ) {
throw new IllegalStateException(
"No transitions allowed from the DESTROYED state" ) ;
}
} ;
private static Guard waitGuard = new GuardBase( "wait" ) {
public Guard.Result evaluate( FSM fsm, Input in ) {
AOMEntry entry = (AOMEntry)fsm ;
try {
entry.wait.await() ;
} catch (InterruptedException exc) {
// XXX Log this
// NO-OP
}
return Guard.Result.DEFERED ;
}
} ;
private static class CounterGuard extends GuardBase {
private int value ;
public CounterGuard( int value )
{
super( "counter>" + value ) ;
this.value = value ;
}
public Guard.Result evaluate( FSM fsm, Input in )
{
AOMEntry entry = (AOMEntry)fsm ;
return Guard.Result.convert( entry.counter[0] > value ) ;
}
} ;
private static GuardBase greaterZeroGuard = new CounterGuard( 0 ) ;
private static Guard zeroGuard = new Guard.Complement( greaterZeroGuard ) ;
private static GuardBase greaterOneGuard = new CounterGuard( 1 ) ;
private static Guard oneGuard = new Guard.Complement( greaterOneGuard ) ;
private static StateEngine engine ;
static {
engine = StateEngineFactory.create() ;
// State, Input, Guard, Action, new State
engine.add( INVALID, ENTER, incrementAction, INCARN ) ;
engine.add( INVALID, ACTIVATE, null, VALID ) ;
engine.setDefault( INVALID ) ;
engine.add( INCARN, ENTER, waitGuard, null, INCARN ) ;
engine.add( INCARN, EXIT, null, INCARN ) ;
engine.add( INCARN, START_ETH, waitGuard, null, INCARN ) ;
engine.add( INCARN, INC_DONE, null, VALID ) ;
engine.add( INCARN, INC_FAIL, decrementAction, INVALID ) ;
engine.add( VALID, ENTER, incrementAction, VALID ) ;
engine.add( VALID, EXIT, decrementAction, VALID ) ;
engine.add( VALID, START_ETH, greaterZeroGuard, null, ETHP ) ;
engine.add( VALID, START_ETH, zeroGuard, null, ETH ) ;
engine.add( ETHP, ENTER, waitGuard, null, ETHP ) ;
engine.add( ETHP, START_ETH, null, ETHP ) ;
engine.add( ETHP, EXIT, greaterOneGuard, decrementAction, ETHP ) ;
engine.add( ETHP, EXIT, oneGuard, decrementAction, ETH ) ;
engine.add( ETH, START_ETH, null, ETH ) ;
engine.add( ETH, ETH_DONE, null, DESTROYED ) ;
engine.add( ETH, ENTER, waitGuard, null, ETH ) ;
engine.setDefault( DESTROYED, throwIllegalStateExceptionAction, DESTROYED ) ;
engine.done() ;
}
public AOMEntry( POAImpl poa )
{
super( engine, INVALID, ((ORB)poa.getORB()).poaFSMDebugFlag ) ;
this.poa = poa ;
etherealizer = new Thread[1] ;
etherealizer[0] = null ;
counter = new int[1] ;
counter[0] = 0 ;
wait = new CondVar( poa.poaMutex,
((ORB)poa.getORB()).poaConcurrencyDebugFlag ) ;
}
// Methods that drive the FSM: the real interface to this class
// Most just call the doIt method, but startEtherealize needs
// the etherealizer.
public void startEtherealize( Thread etherealizer )
{
this.etherealizer[0] = etherealizer ;
doIt( START_ETH ) ;
}
public void etherealizeComplete() { doIt( ETH_DONE ) ; }
public void incarnateComplete() { doIt( INC_DONE ) ; }
public void incarnateFailure() { doIt( INC_FAIL ) ; }
public void activateObject() { doIt( ACTIVATE ) ; }
public void enter() { doIt( ENTER ) ; }
public void exit() { doIt( EXIT ) ; }
}
|