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