| /* |
| * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.corba.se.impl.interceptors; |
| |
| import org.omg.CORBA.CompletionStatus; |
| import org.omg.CORBA.INTERNAL; |
| import org.omg.PortableInterceptor.Current; |
| import org.omg.PortableInterceptor.InvalidSlot; |
| |
| import com.sun.corba.se.impl.corba.AnyImpl; |
| |
| import com.sun.corba.se.impl.logging.InterceptorsSystemException; |
| import com.sun.corba.se.spi.logging.CORBALogDomains; |
| |
| import com.sun.corba.se.spi.orb.ORB; |
| |
| /** |
| * SlotTableStack is the container of SlotTable instances for each thread |
| */ |
| public class SlotTableStack |
| { |
| // SlotTablePool is the container for reusable SlotTables' |
| private class SlotTablePool { |
| |
| // Contains a list of reusable SlotTable |
| private SlotTable[] pool; |
| |
| // High water mark for the pool |
| // If the pool size reaches this limit then putSlotTable will |
| // not put SlotTable to the pool. |
| private final int HIGH_WATER_MARK = 5; |
| |
| // currentIndex points to the last SlotTable in the list |
| private int currentIndex; |
| |
| SlotTablePool( ) { |
| pool = new SlotTable[HIGH_WATER_MARK]; |
| currentIndex = 0; |
| } |
| |
| /** |
| * Puts SlotTable to the re-usable pool. |
| */ |
| void putSlotTable( SlotTable table ) { |
| // If there are enough SlotTables in the pool, then don't add |
| // this table to the pool. |
| if( currentIndex >= HIGH_WATER_MARK ) { |
| // Let the garbage collector collect it. |
| return; |
| } |
| pool[currentIndex] = table; |
| currentIndex++; |
| } |
| |
| /** |
| * Gets SlotTable from the re-usable pool. |
| */ |
| SlotTable getSlotTable( ) { |
| // If there are no entries in the pool then return null |
| if( currentIndex == 0 ) { |
| return null; |
| } |
| // Works like a stack, Gets the last one added first |
| currentIndex--; |
| return pool[currentIndex]; |
| } |
| } |
| |
| // Contains all the active SlotTables for each thread. |
| // The List is made to behave like a stack. |
| private java.util.List tableContainer; |
| |
| // Keeps track of number of PICurrents in the stack. |
| private int currentIndex; |
| |
| // For Every Thread there will be a pool of re-usable SlotTables' |
| // stored in SlotTablePool |
| private SlotTablePool tablePool; |
| |
| // The ORB associated with this slot table stack |
| private ORB orb; |
| |
| private InterceptorsSystemException wrapper ; |
| |
| /** |
| * Constructs the stack and and SlotTablePool |
| */ |
| SlotTableStack( ORB orb, SlotTable table ) { |
| this.orb = orb; |
| wrapper = InterceptorsSystemException.get( orb, CORBALogDomains.RPC_PROTOCOL ) ; |
| |
| currentIndex = 0; |
| tableContainer = new java.util.ArrayList( ); |
| tablePool = new SlotTablePool( ); |
| // SlotTableStack will be created with one SlotTable on the stack. |
| // This table is used as the reference to query for number of |
| // allocated slots to create other slottables. |
| tableContainer.add( currentIndex, table ); |
| currentIndex++; |
| } |
| |
| |
| /** |
| * pushSlotTable pushes a fresh Slot Table on to the stack by doing the |
| * following, |
| * 1: Checks to see if there is any SlotTable in SlotTablePool |
| * If present then use that instance to push into the SlotTableStack |
| * |
| * 2: If there is no SlotTable in the pool, then creates a new one and |
| * pushes that into the SlotTableStack |
| */ |
| void pushSlotTable( ) { |
| SlotTable table = tablePool.getSlotTable( ); |
| if( table == null ) { |
| // get an existing PICurrent to get the slotSize |
| SlotTable tableTemp = peekSlotTable(); |
| table = new SlotTable( orb, tableTemp.getSize( )); |
| } |
| // NOTE: Very important not to always "add" - otherwise a memory leak. |
| if (currentIndex == tableContainer.size()) { |
| // Add will cause the table to grow. |
| tableContainer.add( currentIndex, table ); |
| } else if (currentIndex > tableContainer.size()) { |
| throw wrapper.slotTableInvariant( new Integer( currentIndex ), |
| new Integer( tableContainer.size() ) ) ; |
| } else { |
| // Set will override unused slots. |
| tableContainer.set( currentIndex, table ); |
| } |
| currentIndex++; |
| } |
| |
| /** |
| * popSlotTable does the following |
| * 1: pops the top SlotTable in the SlotTableStack |
| * |
| * 2: resets the slots in the SlotTable which resets the slotvalues to |
| * null if there are any previous sets. |
| * |
| * 3: puts the reset SlotTable into the SlotTablePool to reuse |
| */ |
| void popSlotTable( ) { |
| if( currentIndex <= 1 ) { |
| // Do not pop the SlotTable, If there is only one. |
| // This should not happen, But an extra check for safety. |
| throw wrapper.cantPopOnlyPicurrent() ; |
| } |
| currentIndex--; |
| SlotTable table = (SlotTable)tableContainer.get( currentIndex ); |
| tableContainer.set( currentIndex, null ); // Do not leak memory. |
| table.resetSlots( ); |
| tablePool.putSlotTable( table ); |
| } |
| |
| /** |
| * peekSlotTable gets the top SlotTable from the SlotTableStack without |
| * popping. |
| */ |
| SlotTable peekSlotTable( ) { |
| return (SlotTable) tableContainer.get( currentIndex - 1); |
| } |
| |
| } |
| |
| // End of file. |