1. /*
  2. * @(#)AOMEntry.java 1.28 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.oa.poa ;
  8. import org.omg.CORBA.INTERNAL ;
  9. import com.sun.corba.se.spi.orb.ORB ;
  10. import com.sun.corba.se.spi.orbutil.fsm.Action ;
  11. import com.sun.corba.se.spi.orbutil.fsm.ActionBase ;
  12. import com.sun.corba.se.spi.orbutil.fsm.Guard ;
  13. import com.sun.corba.se.spi.orbutil.fsm.GuardBase ;
  14. import com.sun.corba.se.spi.orbutil.fsm.State ;
  15. import com.sun.corba.se.spi.orbutil.fsm.StateImpl ;
  16. import com.sun.corba.se.spi.orbutil.fsm.Input ;
  17. import com.sun.corba.se.spi.orbutil.fsm.InputImpl ;
  18. import com.sun.corba.se.spi.orbutil.fsm.FSM ;
  19. import com.sun.corba.se.spi.orbutil.fsm.FSMImpl ;
  20. import com.sun.corba.se.spi.orbutil.fsm.StateEngine ;
  21. import com.sun.corba.se.spi.orbutil.fsm.StateEngineFactory ;
  22. import com.sun.corba.se.impl.orbutil.concurrent.Mutex ;
  23. import com.sun.corba.se.impl.orbutil.concurrent.CondVar ;
  24. /** AOMEntry represents a Servant or potential Servant in the ActiveObjectMap.
  25. * It may be in several states to allow for long incarnate or etherealize operations.
  26. * The methods on this class mostly represent input symbols to the state machine
  27. * that controls the lifecycle of the entry. A library is used to build the state
  28. * machine rather than the more usual state pattern so that the state machine
  29. * transitions are explicitly visible.
  30. */
  31. public class AOMEntry extends FSMImpl {
  32. private final Thread[] etherealizer ; // The actual etherealize operation
  33. // for this entry. It is
  34. // represented as a Thread because
  35. // the POA.deactivate_object never
  36. // waits for the completion.
  37. private final int[] counter ; // single element holder for counter
  38. // accessed in actions
  39. private final CondVar wait ; // accessed in actions
  40. final POAImpl poa ;
  41. public static final State INVALID = new StateImpl( "Invalid" ) ;
  42. public static final State INCARN = new StateImpl( "Incarnating" ) {
  43. public void postAction( FSM fsm ) {
  44. AOMEntry entry = (AOMEntry)fsm ;
  45. entry.wait.broadcast() ;
  46. }
  47. };
  48. public static final State VALID = new StateImpl( "Valid" ) ;
  49. public static final State ETHP = new StateImpl( "EtherealizePending" ) ;
  50. public static final State ETH = new StateImpl( "Etherealizing" ) {
  51. public void preAction( FSM fsm ) {
  52. AOMEntry entry = (AOMEntry)fsm ;
  53. Thread etherealizer = entry.etherealizer[0] ;
  54. if (etherealizer != null)
  55. etherealizer.start() ;
  56. }
  57. public void postAction( FSM fsm ) {
  58. AOMEntry entry = (AOMEntry)fsm ;
  59. entry.wait.broadcast() ;
  60. }
  61. };
  62. public static final State DESTROYED = new StateImpl( "Destroyed" ) ;
  63. static final Input START_ETH = new InputImpl( "startEtherealize" ) ;
  64. static final Input ETH_DONE = new InputImpl( "etherealizeDone" ) ;
  65. static final Input INC_DONE = new InputImpl( "incarnateDone" ) ;
  66. static final Input INC_FAIL = new InputImpl( "incarnateFailure" ) ;
  67. static final Input ACTIVATE = new InputImpl( "activateObject" ) ;
  68. static final Input ENTER = new InputImpl( "enter" ) ;
  69. static final Input EXIT = new InputImpl( "exit" ) ;
  70. private static Action incrementAction = new ActionBase( "increment" ) {
  71. public void doIt( FSM fsm, Input in ) {
  72. AOMEntry entry = (AOMEntry)fsm ;
  73. entry.counter[0]++ ;
  74. }
  75. } ;
  76. private static Action decrementAction = new ActionBase( "decrement" ) {
  77. public void doIt( FSM fsm, Input in ) {
  78. AOMEntry entry = (AOMEntry)fsm ;
  79. if (entry.counter[0] > 0)
  80. entry.counter[0]-- ;
  81. else
  82. throw entry.poa.lifecycleWrapper().aomEntryDecZero() ;
  83. }
  84. } ;
  85. private static Action throwIllegalStateExceptionAction = new ActionBase(
  86. "throwIllegalStateException" ) {
  87. public void doIt( FSM fsm, Input in ) {
  88. throw new IllegalStateException(
  89. "No transitions allowed from the DESTROYED state" ) ;
  90. }
  91. } ;
  92. private static Guard waitGuard = new GuardBase( "wait" ) {
  93. public Guard.Result evaluate( FSM fsm, Input in ) {
  94. AOMEntry entry = (AOMEntry)fsm ;
  95. try {
  96. entry.wait.await() ;
  97. } catch (InterruptedException exc) {
  98. // XXX Log this
  99. // NO-OP
  100. }
  101. return Guard.Result.DEFERED ;
  102. }
  103. } ;
  104. private static class CounterGuard extends GuardBase {
  105. private int value ;
  106. public CounterGuard( int value )
  107. {
  108. super( "counter>" + value ) ;
  109. this.value = value ;
  110. }
  111. public Guard.Result evaluate( FSM fsm, Input in )
  112. {
  113. AOMEntry entry = (AOMEntry)fsm ;
  114. return Guard.Result.convert( entry.counter[0] > value ) ;
  115. }
  116. } ;
  117. private static GuardBase greaterZeroGuard = new CounterGuard( 0 ) ;
  118. private static Guard zeroGuard = new Guard.Complement( greaterZeroGuard ) ;
  119. private static GuardBase greaterOneGuard = new CounterGuard( 1 ) ;
  120. private static Guard oneGuard = new Guard.Complement( greaterOneGuard ) ;
  121. private static StateEngine engine ;
  122. static {
  123. engine = StateEngineFactory.create() ;
  124. // State, Input, Guard, Action, new State
  125. engine.add( INVALID, ENTER, incrementAction, INCARN ) ;
  126. engine.add( INVALID, ACTIVATE, null, VALID ) ;
  127. engine.setDefault( INVALID ) ;
  128. engine.add( INCARN, ENTER, waitGuard, null, INCARN ) ;
  129. engine.add( INCARN, EXIT, null, INCARN ) ;
  130. engine.add( INCARN, START_ETH, waitGuard, null, INCARN ) ;
  131. engine.add( INCARN, INC_DONE, null, VALID ) ;
  132. engine.add( INCARN, INC_FAIL, decrementAction, INVALID ) ;
  133. engine.add( VALID, ENTER, incrementAction, VALID ) ;
  134. engine.add( VALID, EXIT, decrementAction, VALID ) ;
  135. engine.add( VALID, START_ETH, greaterZeroGuard, null, ETHP ) ;
  136. engine.add( VALID, START_ETH, zeroGuard, null, ETH ) ;
  137. engine.add( ETHP, ENTER, waitGuard, null, ETHP ) ;
  138. engine.add( ETHP, START_ETH, null, ETHP ) ;
  139. engine.add( ETHP, EXIT, greaterOneGuard, decrementAction, ETHP ) ;
  140. engine.add( ETHP, EXIT, oneGuard, decrementAction, ETH ) ;
  141. engine.add( ETH, START_ETH, null, ETH ) ;
  142. engine.add( ETH, ETH_DONE, null, DESTROYED ) ;
  143. engine.add( ETH, ENTER, waitGuard, null, ETH ) ;
  144. engine.setDefault( DESTROYED, throwIllegalStateExceptionAction, DESTROYED ) ;
  145. engine.done() ;
  146. }
  147. public AOMEntry( POAImpl poa )
  148. {
  149. super( engine, INVALID, ((ORB)poa.getORB()).poaFSMDebugFlag ) ;
  150. this.poa = poa ;
  151. etherealizer = new Thread[1] ;
  152. etherealizer[0] = null ;
  153. counter = new int[1] ;
  154. counter[0] = 0 ;
  155. wait = new CondVar( poa.poaMutex,
  156. ((ORB)poa.getORB()).poaConcurrencyDebugFlag ) ;
  157. }
  158. // Methods that drive the FSM: the real interface to this class
  159. // Most just call the doIt method, but startEtherealize needs
  160. // the etherealizer.
  161. public void startEtherealize( Thread etherealizer )
  162. {
  163. this.etherealizer[0] = etherealizer ;
  164. doIt( START_ETH ) ;
  165. }
  166. public void etherealizeComplete() { doIt( ETH_DONE ) ; }
  167. public void incarnateComplete() { doIt( INC_DONE ) ; }
  168. public void incarnateFailure() { doIt( INC_FAIL ) ; }
  169. public void activateObject() { doIt( ACTIVATE ) ; }
  170. public void enter() { doIt( ENTER ) ; }
  171. public void exit() { doIt( EXIT ) ; }
  172. }