1. /*
  2. * @(#)SlotTableStack.java 1.11 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.interceptors;
  8. import org.omg.CORBA.CompletionStatus;
  9. import org.omg.CORBA.INTERNAL;
  10. import org.omg.PortableInterceptor.Current;
  11. import org.omg.PortableInterceptor.InvalidSlot;
  12. import com.sun.corba.se.impl.corba.AnyImpl;
  13. import com.sun.corba.se.impl.logging.InterceptorsSystemException;
  14. import com.sun.corba.se.spi.logging.CORBALogDomains;
  15. import com.sun.corba.se.spi.orb.ORB;
  16. /**
  17. * SlotTableStack is the container of SlotTable instances for each thread
  18. */
  19. public class SlotTableStack
  20. {
  21. // SlotTablePool is the container for reusable SlotTables'
  22. private class SlotTablePool {
  23. // Contains a list of reusable SlotTable
  24. private SlotTable[] pool;
  25. // High water mark for the pool
  26. // If the pool size reaches this limit then putSlotTable will
  27. // not put SlotTable to the pool.
  28. private final int HIGH_WATER_MARK = 5;
  29. // currentIndex points to the last SlotTable in the list
  30. private int currentIndex;
  31. SlotTablePool( ) {
  32. pool = new SlotTable[HIGH_WATER_MARK];
  33. currentIndex = 0;
  34. }
  35. /**
  36. * Puts SlotTable to the re-usable pool.
  37. */
  38. void putSlotTable( SlotTable table ) {
  39. // If there are enough SlotTables in the pool, then don't add
  40. // this table to the pool.
  41. if( currentIndex >= HIGH_WATER_MARK ) {
  42. // Let the garbage collector collect it.
  43. return;
  44. }
  45. pool[currentIndex] = table;
  46. currentIndex++;
  47. }
  48. /**
  49. * Gets SlotTable from the re-usable pool.
  50. */
  51. SlotTable getSlotTable( ) {
  52. // If there are no entries in the pool then return null
  53. if( currentIndex == 0 ) {
  54. return null;
  55. }
  56. // Works like a stack, Gets the last one added first
  57. currentIndex--;
  58. return pool[currentIndex];
  59. }
  60. }
  61. // Contains all the active SlotTables for each thread.
  62. // The List is made to behave like a stack.
  63. private java.util.List tableContainer;
  64. // Keeps track of number of PICurrents in the stack.
  65. private int currentIndex;
  66. // For Every Thread there will be a pool of re-usable SlotTables'
  67. // stored in SlotTablePool
  68. private SlotTablePool tablePool;
  69. // The ORB associated with this slot table stack
  70. private ORB orb;
  71. private InterceptorsSystemException wrapper ;
  72. /**
  73. * Constructs the stack and and SlotTablePool
  74. */
  75. SlotTableStack( ORB orb, SlotTable table ) {
  76. this.orb = orb;
  77. wrapper = InterceptorsSystemException.get( orb, CORBALogDomains.RPC_PROTOCOL ) ;
  78. currentIndex = 0;
  79. tableContainer = new java.util.ArrayList( );
  80. tablePool = new SlotTablePool( );
  81. // SlotTableStack will be created with one SlotTable on the stack.
  82. // This table is used as the reference to query for number of
  83. // allocated slots to create other slottables.
  84. tableContainer.add( currentIndex, table );
  85. currentIndex++;
  86. }
  87. /**
  88. * pushSlotTable pushes a fresh Slot Table on to the stack by doing the
  89. * following,
  90. * 1: Checks to see if there is any SlotTable in SlotTablePool
  91. * If present then use that instance to push into the SlotTableStack
  92. *
  93. * 2: If there is no SlotTable in the pool, then creates a new one and
  94. * pushes that into the SlotTableStack
  95. */
  96. void pushSlotTable( ) {
  97. SlotTable table = tablePool.getSlotTable( );
  98. if( table == null ) {
  99. // get an existing PICurrent to get the slotSize
  100. SlotTable tableTemp = peekSlotTable();
  101. table = new SlotTable( orb, tableTemp.getSize( ));
  102. }
  103. // NOTE: Very important not to always "add" - otherwise a memory leak.
  104. if (currentIndex == tableContainer.size()) {
  105. // Add will cause the table to grow.
  106. tableContainer.add( currentIndex, table );
  107. } else if (currentIndex > tableContainer.size()) {
  108. throw wrapper.slotTableInvariant( new Integer( currentIndex ),
  109. new Integer( tableContainer.size() ) ) ;
  110. } else {
  111. // Set will override unused slots.
  112. tableContainer.set( currentIndex, table );
  113. }
  114. currentIndex++;
  115. }
  116. /**
  117. * popSlotTable does the following
  118. * 1: pops the top SlotTable in the SlotTableStack
  119. *
  120. * 2: resets the slots in the SlotTable which resets the slotvalues to
  121. * null if there are any previous sets.
  122. *
  123. * 3: puts the reset SlotTable into the SlotTablePool to reuse
  124. */
  125. void popSlotTable( ) {
  126. if( currentIndex <= 1 ) {
  127. // Do not pop the SlotTable, If there is only one.
  128. // This should not happen, But an extra check for safety.
  129. throw wrapper.cantPopOnlyPicurrent() ;
  130. }
  131. currentIndex--;
  132. SlotTable table = (SlotTable)tableContainer.get( currentIndex );
  133. tableContainer.set( currentIndex, null ); // Do not leak memory.
  134. table.resetSlots( );
  135. tablePool.putSlotTable( table );
  136. }
  137. /**
  138. * peekSlotTable gets the top SlotTable from the SlotTableStack without
  139. * popping.
  140. */
  141. SlotTable peekSlotTable( ) {
  142. return (SlotTable) tableContainer.get( currentIndex - 1);
  143. }
  144. }
  145. // End of file.