blob: c19a3843cdd39a88a39caf1dedf54e8898ce86e6 [file] [log] [blame]
/*
* 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.